Home | History | Annotate | Download | only in llvm2ice_tests
      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