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