Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -instcombine -S -default-data-layout="p:32:32:32-p1:16:16:16-n8:16:32:64" < %s | FileCheck %s
      2 
      3 @G16 = internal constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
      4                                      i16 73, i16 82, i16 69, i16 68, i16 0]
      5 
      6 @G16_as1 = internal addrspace(1) constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
      7                                                       i16 73, i16 82, i16 69, i16 68, i16 0]
      8 
      9 @GD = internal constant [6 x double]
     10    [double -10.0, double 1.0, double 4.0, double 2.0, double -20.0, double -40.0]
     11 
     12 %Foo = type { i32, i32, i32, i32 }
     13 
     14 @GS = internal constant %Foo { i32 1, i32 4, i32 9, i32 14 }
     15 
     16 @GStructArr = internal constant [4 x %Foo] [ %Foo { i32 1, i32 4, i32 9, i32 14 },
     17                                              %Foo { i32 5, i32 4, i32 6, i32 11 },
     18                                              %Foo { i32 6, i32 5, i32 9, i32 20 },
     19                                              %Foo { i32 12, i32 3, i32 9, i32 8 } ]
     20 
     21 
     22 define i1 @test1(i32 %X) {
     23   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
     24   %Q = load i16, i16* %P
     25   %R = icmp eq i16 %Q, 0
     26   ret i1 %R
     27 ; CHECK-LABEL: @test1(
     28 ; CHECK-NEXT: %R = icmp eq i32 %X, 9
     29 ; CHECK-NEXT: ret i1 %R
     30 }
     31 
     32 define i1 @test1_noinbounds(i32 %X) {
     33   %P = getelementptr [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
     34   %Q = load i16, i16* %P
     35   %R = icmp eq i16 %Q, 0
     36   ret i1 %R
     37 ; CHECK-LABEL: @test1_noinbounds(
     38 ; CHECK-NEXT: %R = icmp eq i32 %X, 9
     39 ; CHECK-NEXT: ret i1 %R
     40 }
     41 
     42 define i1 @test1_noinbounds_i64(i64 %X) {
     43   %P = getelementptr [10 x i16], [10 x i16]* @G16, i64 0, i64 %X
     44   %Q = load i16, i16* %P
     45   %R = icmp eq i16 %Q, 0
     46   ret i1 %R
     47 ; CHECK-LABEL: @test1_noinbounds_i64(
     48 ; CHECK: %R = icmp eq i32 %1, 9
     49 ; CHECK-NEXT: ret i1 %R
     50 }
     51 
     52 define i1 @test1_noinbounds_as1(i32 %x) {
     53   %p = getelementptr [10 x i16], [10 x i16] addrspace(1)* @G16_as1, i16 0, i32 %x
     54   %q = load i16, i16 addrspace(1)* %p
     55   %r = icmp eq i16 %q, 0
     56   ret i1 %r
     57 
     58 ; CHECK-LABEL: @test1_noinbounds_as1(
     59 ; CHECK-NEXT: trunc i32 %x to i16
     60 ; CHECK-NEXT: %r = icmp eq i16 %1, 9
     61 ; CHECK-NEXT: ret i1 %r
     62 }
     63 
     64 define i1 @test2(i32 %X) {
     65   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
     66   %Q = load i16, i16* %P
     67   %R = icmp slt i16 %Q, 85
     68   ret i1 %R
     69 ; CHECK-LABEL: @test2(
     70 ; CHECK-NEXT:  %R = icmp ne i32 %X, 4
     71 ; CHECK-NEXT:  ret i1 %R
     72 }
     73 
     74 define i1 @test3(i32 %X) {
     75   %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
     76   %Q = load double, double* %P
     77   %R = fcmp oeq double %Q, 1.0
     78   ret i1 %R
     79 ; CHECK-LABEL: @test3(
     80 ; CHECK-NEXT: %R = icmp eq i32 %X, 1
     81 ; CHECK-NEXT: ret i1 %R
     82 
     83 }
     84 
     85 define i1 @test4(i32 %X) {
     86   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
     87   %Q = load i16, i16* %P
     88   %R = icmp sle i16 %Q, 73
     89   ret i1 %R
     90 ; CHECK-LABEL: @test4(
     91 ; CHECK-NEXT: lshr i32 933, %X
     92 ; CHECK-NEXT: and i32 {{.*}}, 1
     93 ; CHECK-NEXT: %R = icmp ne i32 {{.*}}, 0
     94 ; CHECK-NEXT: ret i1 %R
     95 }
     96 
     97 define i1 @test4_i16(i16 %X) {
     98   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i16 %X
     99   %Q = load i16, i16* %P
    100   %R = icmp sle i16 %Q, 73
    101   ret i1 %R
    102 ; CHECK-LABEL: @test4_i16(
    103 ; CHECK-NEXT: sext i16 %X to i32
    104 ; CHECK-NEXT: lshr i32 933, %1
    105 ; CHECK-NEXT: and i32 {{.*}}, 1
    106 ; CHECK-NEXT: %R = icmp ne i32 {{.*}}, 0
    107 ; CHECK-NEXT: ret i1 %R
    108 }
    109 
    110 define i1 @test5(i32 %X) {
    111   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
    112   %Q = load i16, i16* %P
    113   %R = icmp eq i16 %Q, 69
    114   ret i1 %R
    115 ; CHECK-LABEL: @test5(
    116 ; CHECK-NEXT: icmp eq i32 %X, 2
    117 ; CHECK-NEXT: icmp eq i32 %X, 7
    118 ; CHECK-NEXT: %R = or i1
    119 ; CHECK-NEXT: ret i1 %R
    120 }
    121 
    122 define i1 @test6(i32 %X) {
    123   %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
    124   %Q = load double, double* %P
    125   %R = fcmp ogt double %Q, 0.0
    126   ret i1 %R
    127 ; CHECK-LABEL: @test6(
    128 ; CHECK-NEXT: add i32 %X, -1
    129 ; CHECK-NEXT: %R = icmp ult i32 {{.*}}, 3
    130 ; CHECK-NEXT: ret i1 %R
    131 }
    132 
    133 define i1 @test7(i32 %X) {
    134   %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
    135   %Q = load double, double* %P
    136   %R = fcmp olt double %Q, 0.0
    137   ret i1 %R
    138 ; CHECK-LABEL: @test7(
    139 ; CHECK-NEXT: add i32 %X, -1
    140 ; CHECK-NEXT: %R = icmp ugt i32 {{.*}}, 2
    141 ; CHECK-NEXT: ret i1 %R
    142 }
    143 
    144 define i1 @test8(i32 %X) {
    145   %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
    146   %Q = load i16, i16* %P
    147   %R = and i16 %Q, 3
    148   %S = icmp eq i16 %R, 0
    149   ret i1 %S
    150 ; CHECK-LABEL: @test8(
    151 ; CHECK-NEXT: or i32 %X, 1
    152 ; CHECK-NEXT: icmp eq i32 {{.*}}, 9
    153 ; CHECK-NEXT: ret i1
    154 }
    155 
    156 @GA = internal constant [4 x { i32, i32 } ] [
    157   { i32, i32 } { i32 1, i32 0 },
    158   { i32, i32 } { i32 2, i32 1 },
    159   { i32, i32 } { i32 3, i32 1 },
    160   { i32, i32 } { i32 4, i32 0 }
    161 ]
    162 
    163 define i1 @test9(i32 %X) {
    164   %P = getelementptr inbounds [4 x { i32, i32 } ], [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
    165   %Q = load i32, i32* %P
    166   %R = icmp eq i32 %Q, 1
    167   ret i1 %R
    168 ; CHECK-LABEL: @test9(
    169 ; CHECK-NEXT: add i32 %X, -1
    170 ; CHECK-NEXT: icmp ult i32 {{.*}}, 2
    171 ; CHECK-NEXT: ret i1
    172 }
    173 
    174 define i1 @test10_struct(i32 %x) {
    175 ; CHECK-LABEL: @test10_struct(
    176 ; CHECK: ret i1 false
    177   %p = getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
    178   %q = load i32, i32* %p
    179   %r = icmp eq i32 %q, 9
    180   ret i1 %r
    181 }
    182 
    183 define i1 @test10_struct_noinbounds(i32 %x) {
    184 ; CHECK-LABEL: @test10_struct_noinbounds(
    185 ; CHECK: getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
    186   %p = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
    187   %q = load i32, i32* %p
    188   %r = icmp eq i32 %q, 9
    189   ret i1 %r
    190 }
    191 
    192 ; Test that the GEP indices are converted before we ever get here
    193 ; Index < ptr size
    194 define i1 @test10_struct_i16(i16 %x){
    195 ; CHECK-LABEL: @test10_struct_i16(
    196 ; CHECK: ret i1 false
    197   %p = getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
    198   %q = load i32, i32* %p
    199   %r = icmp eq i32 %q, 0
    200   ret i1 %r
    201 }
    202 
    203 ; Test that the GEP indices are converted before we ever get here
    204 ; Index > ptr size
    205 define i1 @test10_struct_i64(i64 %x){
    206 ; CHECK-LABEL: @test10_struct_i64(
    207 ; CHECK: ret i1 false
    208   %p = getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
    209   %q = load i32, i32* %p
    210   %r = icmp eq i32 %q, 0
    211   ret i1 %r
    212 }
    213 
    214 define i1 @test10_struct_noinbounds_i16(i16 %x) {
    215 ; CHECK-LABEL: @test10_struct_noinbounds_i16(
    216 ; CHECK: %1 = sext i16 %x to i32
    217 ; CHECK: getelementptr %Foo, %Foo* @GS, i32 %1, i32 0
    218   %p = getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
    219   %q = load i32, i32* %p
    220   %r = icmp eq i32 %q, 0
    221   ret i1 %r
    222 }
    223 
    224 define i1 @test10_struct_arr(i32 %x) {
    225 ; CHECK-LABEL: @test10_struct_arr(
    226 ; CHECK-NEXT: %r = icmp ne i32 %x, 1
    227 ; CHECK-NEXT: ret i1 %r
    228   %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
    229   %q = load i32, i32* %p
    230   %r = icmp eq i32 %q, 9
    231   ret i1 %r
    232 }
    233 
    234 define i1 @test10_struct_arr_noinbounds(i32 %x) {
    235 ; CHECK-LABEL: @test10_struct_arr_noinbounds(
    236 ; CHECK-NEXT: %r = icmp ne i32 %x, 1
    237 ; CHECK-NEXT: ret i1 %r
    238   %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
    239   %q = load i32, i32* %p
    240   %r = icmp eq i32 %q, 9
    241   ret i1 %r
    242 }
    243 
    244 define i1 @test10_struct_arr_i16(i16 %x) {
    245 ; CHECK-LABEL: @test10_struct_arr_i16(
    246 ; CHECK-NEXT: %r = icmp ne i16 %x, 1
    247 ; CHECK-NEXT: ret i1 %r
    248   %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
    249   %q = load i32, i32* %p
    250   %r = icmp eq i32 %q, 9
    251   ret i1 %r
    252 }
    253 
    254 define i1 @test10_struct_arr_i64(i64 %x) {
    255 ; CHECK-LABEL: @test10_struct_arr_i64(
    256 ; CHECK-NEXT: trunc i64 %x to i32
    257 ; CHECK-NEXT: %r = icmp ne i32 %1, 1
    258 ; CHECK-NEXT: ret i1 %r
    259   %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
    260   %q = load i32, i32* %p
    261   %r = icmp eq i32 %q, 9
    262   ret i1 %r
    263 }
    264 
    265 define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
    266 ; CHECK-LABEL: @test10_struct_arr_noinbounds_i16(
    267 ; CHECK-NEXT: %r = icmp ne i16 %x, 1
    268   %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
    269   %q = load i32, i32* %p
    270   %r = icmp eq i32 %q, 9
    271   ret i1 %r
    272 }
    273 
    274 define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
    275 ; CHECK-LABEL: @test10_struct_arr_noinbounds_i64(
    276 ; CHECK: %r = icmp ne i32 %1, 1
    277 ; CHECK-NEXT: ret i1 %r
    278   %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
    279   %q = load i32, i32* %p
    280   %r = icmp eq i32 %q, 9
    281   ret i1 %r
    282 }
    283