617 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; 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 %s3 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:%.*]], 929; CHECK-NEXT: ret i1 [[R]]30;31 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i32 %X32 %Q = load i16, ptr %P33 %R = icmp eq i16 %Q, 034 ret i1 %R35}36 37define i1 @test1_noinbounds(i32 %X) {38; CHECK-LABEL: @test1_noinbounds(39; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 214748364740; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 941; CHECK-NEXT: ret i1 [[R]]42;43 %P = getelementptr [10 x i16], ptr @G16, i32 0, i32 %X44 %Q = load i16, ptr %P45 %R = icmp eq i16 %Q, 046 ret i1 %R47}48 49define i1 @test1_noinbounds_i64(i64 %X) {50; CHECK-LABEL: @test1_noinbounds_i64(51; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 214748364752; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[TMP1]], 953; CHECK-NEXT: ret i1 [[R]]54;55 %P = getelementptr [10 x i16], ptr @G16, i64 0, i64 %X56 %Q = load i16, ptr %P57 %R = icmp eq i16 %Q, 058 ret i1 %R59}60 61define i1 @test1_noinbounds_as1(i32 %x) {62; CHECK-LABEL: @test1_noinbounds_as1(63; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 3276764; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 965; CHECK-NEXT: ret i1 [[R]]66;67 %p = getelementptr [10 x i16], ptr addrspace(1) @G16_as1, i16 0, i32 %x68 %q = load i16, ptr addrspace(1) %p69 %r = icmp eq i16 %q, 070 ret i1 %r71}72 73define i1 @test1_noinbounds_as2(i64 %x) {74; CHECK-LABEL: @test1_noinbounds_as2(75; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 214748364776; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[TMP1]], 977; CHECK-NEXT: ret i1 [[R]]78;79 %p = getelementptr [10 x i16], ptr addrspace(2) @G16_as2, i16 0, i64 %x80 %q = load i16, ptr addrspace(2) %p81 %r = icmp eq i16 %q, 082 ret i1 %r83}84 85define i1 @test1_noarrayty(i32 %X) {86; CHECK-LABEL: @test1_noarrayty(87; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 988; CHECK-NEXT: ret i1 [[R]]89;90 %P = getelementptr inbounds i16, ptr @G16, i32 %X91 %Q = load i16, ptr %P92 %R = icmp eq i16 %Q, 093 ret i1 %R94}95 96define i1 @test2(i32 %X) {97; CHECK-LABEL: @test2(98; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X:%.*]], 499; CHECK-NEXT: ret i1 [[R]]100;101 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i32 %X102 %Q = load i16, ptr %P103 %R = icmp slt i16 %Q, 85104 ret i1 %R105}106 107define i1 @test3(i32 %X) {108; CHECK-LABEL: @test3(109; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 1110; CHECK-NEXT: ret i1 [[R]]111;112 %P = getelementptr inbounds [6 x double], ptr @GD, i32 0, i32 %X113 %Q = load double, ptr %P114 %R = fcmp oeq double %Q, 1.0115 ret i1 %R116}117 118define i1 @test3_noarrayty(i32 %X) {119; CHECK-LABEL: @test3_noarrayty(120; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 1121; CHECK-NEXT: ret i1 [[R]]122;123 %P = getelementptr inbounds double, ptr @GD, i32 %X124 %Q = load double, ptr %P125 %R = fcmp oeq double %Q, 1.0126 ret i1 %R127}128 129define i1 @test4(i32 %X) {130; CHECK-LABEL: @test4(131; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[X:%.*]]132; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 933133; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP2]], 0134; CHECK-NEXT: ret i1 [[R]]135;136 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i32 %X137 %Q = load i16, ptr %P138 %R = icmp sle i16 %Q, 73139 ret i1 %R140}141 142define i1 @test4_i16(i16 %X) {143; CHECK-LABEL: @test4_i16(144; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i16 [[X:%.*]] to i32145; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1]]146; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 933147; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP3]], 0148; CHECK-NEXT: ret i1 [[R]]149;150 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i16 %X151 %Q = load i16, ptr %P152 %R = icmp sle i16 %Q, 73153 ret i1 %R154}155 156define i1 @test5(i32 %X) {157; CHECK-LABEL: @test5(158; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 2159; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[X]], 7160; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[TMP2]]161; CHECK-NEXT: ret i1 [[R]]162;163 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i32 %X164 %Q = load i16, ptr %P165 %R = icmp eq i16 %Q, 69166 ret i1 %R167}168 169define i1 @test6(i32 %X) {170; CHECK-LABEL: @test6(171; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1172; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[TMP1]], 3173; CHECK-NEXT: ret i1 [[R]]174;175 %P = getelementptr inbounds [6 x double], ptr @GD, i32 0, i32 %X176 %Q = load double, ptr %P177 %R = fcmp ogt double %Q, 0.0178 ret i1 %R179}180 181define i1 @test7(i32 %X) {182; CHECK-LABEL: @test7(183; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4184; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[TMP1]], -3185; CHECK-NEXT: ret i1 [[R]]186;187 %P = getelementptr inbounds [6 x double], ptr @GD, i32 0, i32 %X188 %Q = load double, ptr %P189 %R = fcmp olt double %Q, 0.0190 ret i1 %R191}192 193define i1 @test8(i32 %X) {194; CHECK-LABEL: @test8(195; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2196; CHECK-NEXT: [[S:%.*]] = icmp eq i32 [[TMP1]], 8197; CHECK-NEXT: ret i1 [[S]]198;199 %P = getelementptr inbounds [10 x i16], ptr @G16, i32 0, i32 %X200 %Q = load i16, ptr %P201 %R = and i16 %Q, 3202 %S = icmp eq i16 %R, 0203 ret i1 %S204}205 206@GA = internal constant [4 x { i32, i32 } ] [207 { i32, i32 } { i32 1, i32 0 },208 { i32, i32 } { i32 2, i32 1 },209 { i32, i32 } { i32 3, i32 1 },210 { i32, i32 } { i32 4, i32 0 }211]212 213define i1 @test9(i32 %X) {214; CHECK-LABEL: @test9(215; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1216; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[TMP1]], 2217; CHECK-NEXT: ret i1 [[R]]218;219 %P = getelementptr inbounds [4 x { i32, i32 } ], ptr @GA, i32 0, i32 %X, i32 1220 %Q = load i32, ptr %P221 %R = icmp eq i32 %Q, 1222 ret i1 %R223}224 225define i1 @test10_struct(i32 %x) {226; CHECK-LABEL: @test10_struct(227; CHECK-NEXT: ret i1 false228;229 %p = getelementptr inbounds %Foo, ptr @GS, i32 %x, i32 0230 %q = load i32, ptr %p231 %r = icmp eq i32 %q, 9232 ret i1 %r233}234 235define i1 @test10_struct_noinbounds(i32 %x) {236; CHECK-LABEL: @test10_struct_noinbounds(237; CHECK-NEXT: ret i1 false238;239 %p = getelementptr %Foo, ptr @GS, i32 %x, i32 0240 %q = load i32, ptr %p241 %r = icmp eq i32 %q, 9242 ret i1 %r243}244 245; Test that the GEP indices are converted before we ever get here246; Index < ptr size247define i1 @test10_struct_i16(i16 %x){248; CHECK-LABEL: @test10_struct_i16(249; CHECK-NEXT: ret i1 false250;251 %p = getelementptr inbounds %Foo, ptr @GS, i16 %x, i32 0252 %q = load i32, ptr %p253 %r = icmp eq i32 %q, 0254 ret i1 %r255}256 257; Test that the GEP indices are converted before we ever get here258; Index > ptr size259define i1 @test10_struct_i64(i64 %x){260; CHECK-LABEL: @test10_struct_i64(261; CHECK-NEXT: ret i1 false262;263 %p = getelementptr inbounds %Foo, ptr @GS, i64 %x, i32 0264 %q = load i32, ptr %p265 %r = icmp eq i32 %q, 0266 ret i1 %r267}268 269define i1 @test10_struct_noinbounds_i16(i16 %x) {270; CHECK-LABEL: @test10_struct_noinbounds_i16(271; CHECK-NEXT: ret i1 false272;273 %p = getelementptr %Foo, ptr @GS, i16 %x, i32 0274 %q = load i32, ptr %p275 %r = icmp eq i32 %q, 0276 ret i1 %r277}278 279define i1 @test10_struct_arr(i32 %x) {280; CHECK-LABEL: @test10_struct_arr(281; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X:%.*]], 1282; CHECK-NEXT: ret i1 [[R]]283;284 %p = getelementptr inbounds [4 x %Foo], ptr @GStructArr, i32 0, i32 %x, i32 2285 %q = load i32, ptr %p286 %r = icmp eq i32 %q, 9287 ret i1 %r288}289 290define i1 @test10_struct_arr_noinbounds(i32 %x) {291; CHECK-LABEL: @test10_struct_arr_noinbounds(292; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 268435455293; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 1294; CHECK-NEXT: ret i1 [[R]]295;296 %p = getelementptr [4 x %Foo], ptr @GStructArr, i32 0, i32 %x, i32 2297 %q = load i32, ptr %p298 %r = icmp eq i32 %q, 9299 ret i1 %r300}301 302define i1 @test10_struct_arr_i16(i16 %x) {303; CHECK-LABEL: @test10_struct_arr_i16(304; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[X:%.*]], 1305; CHECK-NEXT: ret i1 [[R]]306;307 %p = getelementptr inbounds [4 x %Foo], ptr @GStructArr, i16 0, i16 %x, i32 2308 %q = load i32, ptr %p309 %r = icmp eq i32 %q, 9310 ret i1 %r311}312 313define i1 @test10_struct_arr_i64(i64 %x) {314; CHECK-LABEL: @test10_struct_arr_i64(315; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[X:%.*]], 1316; CHECK-NEXT: ret i1 [[R]]317;318 %p = getelementptr inbounds [4 x %Foo], ptr @GStructArr, i64 0, i64 %x, i32 2319 %q = load i32, ptr %p320 %r = icmp eq i32 %q, 9321 ret i1 %r322}323 324define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {325; CHECK-LABEL: @test10_struct_arr_noinbounds_i16(326; CHECK-NEXT: [[R:%.*]] = icmp ne i16 [[X:%.*]], 1327; CHECK-NEXT: ret i1 [[R]]328;329 %p = getelementptr [4 x %Foo], ptr @GStructArr, i32 0, i16 %x, i32 2330 %q = load i32, ptr %p331 %r = icmp eq i32 %q, 9332 ret i1 %r333}334 335define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {336; CHECK-LABEL: @test10_struct_arr_noinbounds_i64(337; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 268435455338; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[TMP1]], 1339; CHECK-NEXT: ret i1 [[R]]340;341 %p = getelementptr [4 x %Foo], ptr @GStructArr, i32 0, i64 %x, i32 2342 %q = load i32, ptr %p343 %r = icmp eq i32 %q, 9344 ret i1 %r345}346 347define i1 @test10_struct_arr_noarrayty(i32 %x) {348; CHECK-LABEL: @test10_struct_arr_noarrayty(349; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X:%.*]], 1350; CHECK-NEXT: ret i1 [[R]]351;352 %p = getelementptr inbounds %Foo, ptr @GStructArr, i32 %x, i32 2353 %q = load i32, ptr %p354 %r = icmp eq i32 %q, 9355 ret i1 %r356}357 358@table = internal constant [2 x ptr] [ptr @g, ptr getelementptr (i8, ptr @g, i64 4)], align 16359@g = external global [2 x i32]360 361define i1 @pr93017(i64 %idx) {362; CHECK-LABEL: @pr93017(363; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[IDX:%.*]] to i32364; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr @table, i32 [[TMP1]]365; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[GEP]], align 4366; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[V]], null367; CHECK-NEXT: ret i1 [[CMP]]368;369 %gep = getelementptr inbounds [2 x ptr], ptr @table, i64 0, i64 %idx370 %v = load ptr, ptr %gep371 %cmp = icmp ne ptr %v, null372 ret i1 %cmp373}374 375@g_i32_lo = internal constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]376 377; Mask is 0b10101010378define i1 @load_vs_array_type_mismatch1(i32 %idx) {379; CHECK-LABEL: @load_vs_array_type_mismatch1(380; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1:%.*]]381; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 170382; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP3]], 0383; CHECK-NEXT: ret i1 [[CMP]]384;385 %gep = getelementptr inbounds i16, ptr @g_i32_lo, i32 %idx386 %load = load i16, ptr %gep387 %cmp = icmp eq i16 %load, 0388 ret i1 %cmp389}390 391@g_i32_hi = internal constant [4 x i32] [i32 u0x00010000, i32 u0x00020000, i32 u0x00030000, i32 u0x00040000]392 393; Mask is 0b01010101394define i1 @load_vs_array_type_mismatch2(i32 %idx) {395; CHECK-LABEL: @load_vs_array_type_mismatch2(396; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1:%.*]]397; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 85398; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP3]], 0399; CHECK-NEXT: ret i1 [[CMP]]400;401 %gep = getelementptr inbounds i16, ptr @g_i32_hi, i32 %idx402 %load = load i16, ptr %gep403 %cmp = icmp eq i16 %load, 0404 ret i1 %cmp405}406 407@g_i16_1 = internal constant [8 x i16] [i16 0, i16 1, i16 1, i16 0, i16 0, i16 1, i16 1, i16 0]408 409; idx == 1 || idx == 3410define i1 @load_vs_array_type_mismatch_offset1(i32 %idx) {411; CHECK-LABEL: @load_vs_array_type_mismatch_offset1(412; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3413; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1414; CHECK-NEXT: ret i1 [[CMP]]415;416 %gep = getelementptr inbounds {i16, i16}, ptr @g_i16_1, i32 %idx, i32 1417 %load = load i16, ptr %gep418 %cmp = icmp eq i16 %load, 0419 ret i1 %cmp420}421 422define i1 @load_vs_array_type_mismatch_offset1_separate_gep(i32 %idx) {423; CHECK-LABEL: @load_vs_array_type_mismatch_offset1_separate_gep(424; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3425; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1426; CHECK-NEXT: ret i1 [[CMP]]427;428 %gep1 = getelementptr inbounds {i16, i16}, ptr @g_i16_1, i32 %idx429 %gep2 = getelementptr inbounds i8, ptr %gep1, i32 2430 %load = load i16, ptr %gep2431 %cmp = icmp eq i16 %load, 0432 ret i1 %cmp433}434 435define i1 @load_vs_array_type_mismatch_offset1_separate_gep_swapped(i32 %idx) {436; CHECK-LABEL: @load_vs_array_type_mismatch_offset1_separate_gep_swapped(437; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3438; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1439; CHECK-NEXT: ret i1 [[CMP]]440;441 %gep1 = getelementptr inbounds i8, ptr @g_i16_1, i32 2442 %gep2 = getelementptr inbounds {i16, i16}, ptr %gep1, i32 %idx443 %load = load i16, ptr %gep2444 %cmp = icmp eq i16 %load, 0445 ret i1 %cmp446}447 448@g_i16_2 = internal constant [8 x i16] [i16 1, i16 0, i16 0, i16 1, i16 1, i16 0, i16 0, i16 1]449 450; idx == 0 || idx == 2451define i1 @load_vs_array_type_mismatch_offset2(i32 %idx) {452; CHECK-LABEL: @load_vs_array_type_mismatch_offset2(453; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3454; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0455; CHECK-NEXT: ret i1 [[CMP]]456;457 %gep = getelementptr inbounds {i16, i16}, ptr @g_i16_2, i32 %idx, i32 1458 %load = load i16, ptr %gep459 %cmp = icmp eq i16 %load, 0460 ret i1 %cmp461}462 463define i1 @offset_larger_than_stride(i32 %idx) {464; CHECK-LABEL: @offset_larger_than_stride(465; CHECK-NEXT: [[GEP:%.*]] = getelementptr i16, ptr getelementptr inbounds nuw (i8, ptr @g_i16_1, i32 4), i32 [[IDX:%.*]]466; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2467; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0468; CHECK-NEXT: ret i1 [[CMP]]469;470 %gep = getelementptr [2 x i16], ptr @g_i16_1, i64 1, i32 %idx471 %load = load i16, ptr %gep472 %cmp = icmp eq i16 %load, 0473 ret i1 %cmp474}475 476define i1 @load_size_larger_stride(i32 %idx) {477; CHECK-LABEL: @load_size_larger_stride(478; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr @g_i16_1, i32 [[IDX:%.*]]479; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2480; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0481; CHECK-NEXT: ret i1 [[CMP]]482;483 %gep = getelementptr i8, ptr @g_i16_1, i32 %idx484 %load = load i16, ptr %gep485 %cmp = icmp eq i16 %load, 0486 ret i1 %cmp487}488 489@CG_MESSY = constant [9 x i32] [i32 1, i32 7, i32 -1, i32 5, i32 4, i32 1, i32 1, i32 5, i32 4]490 491define i1 @cmp_load_constant_array_messy(i32 %x){492; CHECK-LABEL: @cmp_load_constant_array_messy(493; CHECK-NEXT: entry:494; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0:%.*]], 1073741823495; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1]]496; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 373497; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[TMP3]], 0498; CHECK-NEXT: ret i1 [[COND]]499;500 501entry:502 %isOK_ptr = getelementptr i32, ptr @CG_MESSY, i32 %x503 %isOK = load i32, ptr %isOK_ptr504 %cond = icmp slt i32 %isOK, 5505 ret i1 %cond506}507 508define i1 @cmp_diff_load_constant_array_messy0(i32 %x){509; CHECK-LABEL: @cmp_diff_load_constant_array_messy0(510; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1:%.*]], 1073741823511; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 1, [[TMP2]]512; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 373513; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[TMP4]], 0514; CHECK-NEXT: ret i1 [[COND]]515;516 %isOK_ptr = getelementptr i32, ptr @CG_MESSY, i32 %x517 %isOK = load i16, ptr %isOK_ptr518 %cond = icmp slt i16 %isOK, 5519 ret i1 %cond520}521 522; Load size larger than store size currently not supported.523define i1 @cmp_diff_load_constant_array_messy1(i32 %x){524; CHECK-LABEL: @cmp_diff_load_constant_array_messy1(525; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr i6, ptr @CG_MESSY, i32 [[TMP1:%.*]]526; CHECK-NEXT: [[ISOK:%.*]] = load i16, ptr [[ISOK_PTR]], align 2527; CHECK-NEXT: [[COND:%.*]] = icmp slt i16 [[ISOK]], 5528; CHECK-NEXT: ret i1 [[COND]]529;530 %isOK_ptr = getelementptr i6, ptr @CG_MESSY, i32 %x531 %isOK = load i16, ptr %isOK_ptr532 %cond = icmp slt i16 %isOK, 5533 ret i1 %cond534}535 536define i1 @cmp_load_constant_array_variable_icmp(i32 %x, i32 %y) {537; CHECK-LABEL: @cmp_load_constant_array_variable_icmp(538; CHECK-NEXT: entry:539; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG_MESSY, i32 [[X:%.*]]540; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4541; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], [[Y:%.*]]542; CHECK-NEXT: ret i1 [[COND]]543;544entry:545 %isOK_ptr = getelementptr inbounds i32, ptr @CG_MESSY, i32 %x546 %isOK = load i32, ptr %isOK_ptr547 %cond = icmp ult i32 %isOK, %y548 ret i1 %cond549}550 551@CG_CLEAR = constant [10 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9]552 553; Offsets not supported if negative or larger than stride.554define i1 @cmp_load_constant_additional_positive_offset(i32 %x) {555; CHECK-LABEL: @cmp_load_constant_additional_positive_offset(556; CHECK-NEXT: entry:557; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr getelementptr inbounds nuw (i8, ptr @CG_CLEAR, i32 20), i32 [[X:%.*]]558; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4559; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], 5560; CHECK-NEXT: ret i1 [[COND]]561;562entry:563 %isOK_ptr = getelementptr inbounds [1 x i32], ptr @CG_CLEAR, i32 5, i32 %x564 %isOK = load i32, ptr %isOK_ptr565 %cond = icmp ult i32 %isOK, 5566 ret i1 %cond567}568 569define i1 @cmp_load_constant_additional_negative_offset(i32 %x) {570; CHECK-LABEL: @cmp_load_constant_additional_negative_offset(571; CHECK-NEXT: entry:572; CHECK-NEXT: [[ISOK_PTR_SPLIT:%.*]] = getelementptr inbounds [1 x i32], ptr @CG_CLEAR, i32 [[X:%.*]]573; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i8, ptr [[ISOK_PTR_SPLIT]], i32 -20574; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4575; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], 5576; CHECK-NEXT: ret i1 [[COND]]577;578entry:579 %isOK_ptr = getelementptr inbounds [1 x i32], ptr @CG_CLEAR, i32 %x, i32 -5580 %isOK = load i32, ptr %isOK_ptr581 %cond = icmp ult i32 %isOK, 5582 ret i1 %cond583}584 585define i1 @cmp_load_multiple_indices(i32 %idx, i32 %idx2) {586; CHECK-LABEL: @cmp_load_multiple_indices(587; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i16, ptr @g_i16_1, i32 [[IDX:%.*]]588; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i16, ptr [[GEP1]], i32 [[IDX2:%.*]]589; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP2]], i32 2590; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP3]], align 2591; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0592; CHECK-NEXT: ret i1 [[CMP]]593;594 %gep1 = getelementptr inbounds i16, ptr @g_i16_1, i32 %idx595 %gep2 = getelementptr inbounds i16, ptr %gep1, i32 %idx2596 %gep3 = getelementptr inbounds i8, ptr %gep2, i32 2597 %load = load i16, ptr %gep3598 %cmp = icmp eq i16 %load, 0599 ret i1 %cmp600}601 602define i1 @cmp_load_multiple_indices2(i32 %idx, i32 %idx2) {603; CHECK-LABEL: @cmp_load_multiple_indices2(604; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr inbounds [1 x i16], ptr @g_i16_1, i32 [[IDX:%.*]]605; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i16, ptr [[GEP1_SPLIT]], i32 [[IDX2:%.*]]606; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP1]], i32 2607; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP2]], align 2608; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0609; CHECK-NEXT: ret i1 [[CMP]]610;611 %gep1 = getelementptr inbounds [1 x i16], ptr @g_i16_1, i32 %idx, i32 %idx2612 %gep2 = getelementptr inbounds i8, ptr %gep1, i32 2613 %load = load i16, ptr %gep2614 %cmp = icmp eq i16 %load, 0615 ret i1 %cmp616}617