1 ; Tests desired and undesired folding of load instructions into cast 2 ; instructions. The folding is only done when liveness analysis is performed, 3 ; so only O2 is tested. 4 5 ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s 6 7 ; Not testing trunc, or 32-bit bitcast, because the lowered code uses pretty 8 ; much the same mov instructions regardless of whether folding is done. 9 10 define internal i32 @zext_fold(i32 %arg) { 11 entry: 12 %ptr = add i32 %arg, 200 13 %addr = inttoptr i32 %ptr to i8* 14 %load = load i8, i8* %addr, align 1 15 %result = zext i8 %load to i32 16 ret i32 %result 17 } 18 ; CHECK-LABEL: zext_fold 19 ; CHECK: movzx {{.*}},BYTE PTR [{{.*}}+0xc8] 20 21 define internal i32 @zext_nofold(i32 %arg) { 22 entry: 23 %ptr = add i32 %arg, 200 24 %addr = inttoptr i32 %ptr to i8* 25 %load = load i8, i8* %addr, align 1 26 %tmp1 = zext i8 %load to i32 27 %tmp2 = zext i8 %load to i32 28 %result = add i32 %tmp1, %tmp2 29 ret i32 %result 30 } 31 ; Test that load folding does not happen. 32 ; CHECK-LABEL: zext_nofold 33 ; CHECK-NOT: movzx {{.*}},BYTE PTR [{{.*}}+0xc8] 34 35 define internal i32 @sext_fold(i32 %arg) { 36 entry: 37 %ptr = add i32 %arg, 200 38 %addr = inttoptr i32 %ptr to i8* 39 %load = load i8, i8* %addr, align 1 40 %result = sext i8 %load to i32 41 ret i32 %result 42 } 43 ; CHECK-LABEL: sext_fold 44 ; CHECK: movsx {{.*}},BYTE PTR [{{.*}}+0xc8] 45 46 define internal i32 @sext_nofold(i32 %arg) { 47 entry: 48 %ptr = add i32 %arg, 200 49 %addr = inttoptr i32 %ptr to i8* 50 %load = load i8, i8* %addr, align 1 51 %tmp1 = sext i8 %load to i32 52 %tmp2 = sext i8 %load to i32 53 %result = add i32 %tmp1, %tmp2 54 ret i32 %result 55 } 56 ; Test that load folding does not happen. 57 ; CHECK-LABEL: sext_nofold 58 ; CHECK-NOT: movsx {{.*}},BYTE PTR [{{.*}}+0xc8] 59 60 define internal float @fptrunc_fold(i32 %arg) { 61 entry: 62 %ptr = add i32 %arg, 200 63 %addr = inttoptr i32 %ptr to double* 64 %load = load double, double* %addr, align 8 65 %result = fptrunc double %load to float 66 ret float %result 67 } 68 ; CHECK-LABEL: fptrunc_fold 69 ; CHECK: cvtsd2ss {{.*}},QWORD PTR [{{.*}}+0xc8] 70 71 define internal float @fptrunc_nofold(i32 %arg) { 72 entry: 73 %ptr = add i32 %arg, 200 74 %addr = inttoptr i32 %ptr to double* 75 %load = load double, double* %addr, align 8 76 %tmp1 = fptrunc double %load to float 77 %tmp2 = fptrunc double %load to float 78 %result = fadd float %tmp1, %tmp2 79 ret float %result 80 } 81 ; Test that load folding does not happen. 82 ; CHECK-LABEL: fptrunc_nofold 83 ; CHECK-NOT: cvtsd2ss {{.*}},QWORD PTR [{{.*}}+0xc8] 84 85 define internal double @fpext_fold(i32 %arg) { 86 entry: 87 %ptr = add i32 %arg, 200 88 %addr = inttoptr i32 %ptr to float* 89 %load = load float, float* %addr, align 4 90 %result = fpext float %load to double 91 ret double %result 92 } 93 ; CHECK-LABEL: fpext_fold 94 ; CHECK: cvtss2sd {{.*}},DWORD PTR [{{.*}}+0xc8] 95 96 define internal double @fpext_nofold(i32 %arg) { 97 entry: 98 %ptr = add i32 %arg, 200 99 %addr = inttoptr i32 %ptr to float* 100 %load = load float, float* %addr, align 4 101 %tmp1 = fpext float %load to double 102 %tmp2 = fpext float %load to double 103 %result = fadd double %tmp1, %tmp2 104 ret double %result 105 } 106 ; Test that load folding does not happen. 107 ; CHECK-LABEL: fpext_nofold 108 ; CHECK-NOT: cvtss2sd {{.*}},DWORD PTR [{{.*}}+0xc8] 109 110 define internal i32 @fptoui_fold(i32 %arg) { 111 entry: 112 %ptr = add i32 %arg, 200 113 %addr = inttoptr i32 %ptr to double* 114 %load = load double, double* %addr, align 8 115 %result = fptoui double %load to i16 116 %result2 = zext i16 %result to i32 117 ret i32 %result2 118 } 119 ; CHECK-LABEL: fptoui_fold 120 ; CHECK: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8] 121 122 define internal i32 @fptoui_nofold(i32 %arg) { 123 entry: 124 %ptr = add i32 %arg, 200 125 %addr = inttoptr i32 %ptr to double* 126 %load = load double, double* %addr, align 8 127 %tmp1 = fptoui double %load to i16 128 %tmp2 = fptoui double %load to i16 129 %result = add i16 %tmp1, %tmp2 130 %result2 = zext i16 %result to i32 131 ret i32 %result2 132 } 133 ; Test that load folding does not happen. 134 ; CHECK-LABEL: fptoui_nofold 135 ; CHECK-NOT: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8] 136 137 define internal i32 @fptosi_fold(i32 %arg) { 138 entry: 139 %ptr = add i32 %arg, 200 140 %addr = inttoptr i32 %ptr to double* 141 %load = load double, double* %addr, align 8 142 %result = fptosi double %load to i16 143 %result2 = zext i16 %result to i32 144 ret i32 %result2 145 } 146 ; CHECK-LABEL: fptosi_fold 147 ; CHECK: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8] 148 149 define internal i32 @fptosi_nofold(i32 %arg) { 150 entry: 151 %ptr = add i32 %arg, 200 152 %addr = inttoptr i32 %ptr to double* 153 %load = load double, double* %addr, align 8 154 %tmp1 = fptosi double %load to i16 155 %tmp2 = fptosi double %load to i16 156 %result = add i16 %tmp1, %tmp2 157 %result2 = zext i16 %result to i32 158 ret i32 %result2 159 } 160 ; Test that load folding does not happen. 161 ; CHECK-LABEL: fptosi_nofold 162 ; CHECK-NOT: cvttsd2si {{.*}},QWORD PTR [{{.*}}+0xc8] 163 164 define internal double @uitofp_fold(i32 %arg) { 165 entry: 166 %ptr = add i32 %arg, 200 167 %addr = inttoptr i32 %ptr to i16* 168 %load = load i16, i16* %addr, align 1 169 %result = uitofp i16 %load to double 170 ret double %result 171 } 172 ; CHECK-LABEL: uitofp_fold 173 ; CHECK: movzx {{.*}},WORD PTR [{{.*}}+0xc8] 174 175 define internal double @uitofp_nofold(i32 %arg) { 176 entry: 177 %ptr = add i32 %arg, 200 178 %addr = inttoptr i32 %ptr to i16* 179 %load = load i16, i16* %addr, align 1 180 %tmp1 = uitofp i16 %load to double 181 %tmp2 = uitofp i16 %load to double 182 %result = fadd double %tmp1, %tmp2 183 ret double %result 184 } 185 ; Test that load folding does not happen. 186 ; CHECK-LABEL: uitofp_nofold 187 ; CHECK-NOT: movzx {{.*}},WORD PTR [{{.*}}+0xc8] 188 189 define internal double @sitofp_fold(i32 %arg) { 190 entry: 191 %ptr = add i32 %arg, 200 192 %addr = inttoptr i32 %ptr to i16* 193 %load = load i16, i16* %addr, align 1 194 %result = sitofp i16 %load to double 195 ret double %result 196 } 197 ; CHECK-LABEL: sitofp_fold 198 ; CHECK: movsx {{.*}},WORD PTR [{{.*}}+0xc8] 199 200 define internal double @sitofp_nofold(i32 %arg) { 201 entry: 202 %ptr = add i32 %arg, 200 203 %addr = inttoptr i32 %ptr to i16* 204 %load = load i16, i16* %addr, align 1 205 %tmp1 = sitofp i16 %load to double 206 %tmp2 = sitofp i16 %load to double 207 %result = fadd double %tmp1, %tmp2 208 ret double %result 209 } 210 ; Test that load folding does not happen. 211 ; CHECK-LABEL: sitofp_nofold 212 ; CHECK-NOT: movsx {{.*}},WORD PTR [{{.*}}+0xc8] 213 214 define internal double @bitcast_i64_fold(i32 %arg) { 215 entry: 216 %ptr = add i32 %arg, 200 217 %addr = inttoptr i32 %ptr to i64* 218 %load = load i64, i64* %addr, align 1 219 %result = bitcast i64 %load to double 220 ret double %result 221 } 222 ; CHECK-LABEL: bitcast_i64_fold 223 ; CHECK: movq {{.*}},QWORD PTR [{{.*}}+0xc8] 224 225 define internal double @bitcast_i64_nofold(i32 %arg) { 226 entry: 227 %ptr = add i32 %arg, 200 228 %addr = inttoptr i32 %ptr to i64* 229 %load = load i64, i64* %addr, align 1 230 %tmp1 = bitcast i64 %load to double 231 %tmp2 = bitcast i64 %load to double 232 %result = fadd double %tmp1, %tmp2 233 ret double %result 234 } 235 ; Test that load folding does not happen. 236 ; CHECK-LABEL: bitcast_i64_nofold 237 ; CHECK-NOT: movq {{.*}},QWORD PTR [{{.*}}+0xc8] 238 239 define internal i64 @bitcast_double_fold(i32 %arg) { 240 entry: 241 %ptr = add i32 %arg, 200 242 %addr = inttoptr i32 %ptr to double* 243 %load = load double, double* %addr, align 8 244 %result = bitcast double %load to i64 245 ret i64 %result 246 } 247 ; CHECK-LABEL: bitcast_double_fold 248 ; CHECK-NOT: QWORD PTR 249 ; CHECK: mov {{.*}},DWORD PTR [{{.*}}+0xc8] 250 ; CHECK: mov {{.*}},DWORD PTR [{{.*}}+0xcc] 251 ; CHECK-NOT: QWORD PTR 252 253 define internal i64 @bitcast_double_nofold(i32 %arg) { 254 entry: 255 %ptr = add i32 %arg, 200 256 %addr = inttoptr i32 %ptr to double* 257 %load = load double, double* %addr, align 8 258 %tmp1 = bitcast double %load to i64 259 %tmp2 = bitcast double %load to i64 260 %result = add i64 %tmp1, %tmp2 261 ret i64 %result 262 } 263 ; Test that load folding does not happen. 264 ; CHECK-LABEL: bitcast_double_nofold 265 ; CHECK: QWORD PTR 266 ; CHECK: QWORD PTR 267