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