OLD | NEW |
(Empty) | |
| 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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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* %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 |
OLD | NEW |