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