brintos

brintos / llvm-project-archived public Read only

0
0
Text · 67.5 KiB · 92b76c5 Raw
2074 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64-f16:32"5 6%intstruct = type { i32 }7%pair = type { i32, i32 }8%struct.B = type { double }9%struct.A = type { %struct.B, i32, i32 }10%struct.C = type { [7 x i8] }11 12 13@Global = external global [10 x i8]14@Global_as1 = external addrspace(1) global [10 x i8]15 16declare void @use(ptr)17declare void @use.i64(i64)18 19; Test noop elimination20define ptr @test1(ptr %I) {21; CHECK-LABEL: @test1(22; CHECK-NEXT:    ret ptr [[I:%.*]]23;24  ret ptr %I25}26 27define ptr addrspace(1) @test1_as1(ptr addrspace(1) %I) {28; CHECK-LABEL: @test1_as1(29; CHECK-NEXT:    ret ptr addrspace(1) [[I:%.*]]30;31  ret ptr addrspace(1) %I32}33 34; Test noop elimination35define ptr @test2(ptr %I) {36; CHECK-LABEL: @test2(37; CHECK-NEXT:    ret ptr [[I:%.*]]38;39  %A = getelementptr i32, ptr %I40  ret ptr %A41}42 43; Test that two array indexing geps fold44define ptr @test3(ptr %I) {45; CHECK-LABEL: @test3(46; CHECK-NEXT:    [[B:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 8447; CHECK-NEXT:    ret ptr [[B]]48;49  %A = getelementptr i32, ptr %I, i64 1750  %B = getelementptr i32, ptr %A, i64 451  ret ptr %B52}53 54; Test that two getelementptr insts fold55define ptr @test4(ptr %I) {56; CHECK-LABEL: @test4(57; CHECK-NEXT:    [[A:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 458; CHECK-NEXT:    ret ptr [[A]]59;60  %A = getelementptr { i32 }, ptr %I, i64 161  ret ptr %A62}63 64define void @test5(i8 %B) {65        ; This should be turned into a constexpr instead of being an instruction66; CHECK-LABEL: @test5(67; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds nuw (i8, ptr @Global, i64 4), align 168; CHECK-NEXT:    ret void69;70  %A = getelementptr [10 x i8], ptr @Global, i64 0, i64 471  store i8 %B, ptr %A72  ret void73}74 75define void @test5_as1(i8 %B) {76        ; This should be turned into a constexpr instead of being an instruction77; CHECK-LABEL: @test5_as1(78; CHECK-NEXT:    store i8 [[B:%.*]], ptr addrspace(1) getelementptr inbounds nuw (i8, ptr addrspace(1) @Global_as1, i16 4), align 179; CHECK-NEXT:    ret void80;81  %A = getelementptr [10 x i8], ptr addrspace(1) @Global_as1, i16 0, i16 482  store i8 %B, ptr addrspace(1) %A83  ret void84}85 86%as1_ptr_struct = type { ptr addrspace(1) }87%as2_ptr_struct = type { ptr addrspace(2) }88 89@global_as2 = addrspace(2) global i32 zeroinitializer90@global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { ptr addrspace(2) @global_as2 }91 92; This should be turned into a constexpr instead of being an instruction93define void @test_evaluate_gep_nested_as_ptrs(ptr addrspace(2) %B) {94; CHECK-LABEL: @test_evaluate_gep_nested_as_ptrs(95; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) @global_as1_as2_ptr, align 496; CHECK-NEXT:    ret void97;98  store ptr addrspace(2) %B, ptr addrspace(1) @global_as1_as2_ptr99  ret void100}101 102@arst = addrspace(1) global [4 x ptr addrspace(2)] zeroinitializer103 104define void @test_evaluate_gep_as_ptrs_array(ptr addrspace(2) %B) {105; CHECK-LABEL: @test_evaluate_gep_as_ptrs_array(106; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) getelementptr inbounds nuw (i8, ptr addrspace(1) @arst, i16 8), align 4107; CHECK-NEXT:    ret void108;109 110  %A = getelementptr [4 x ptr addrspace(2)], ptr addrspace(1) @arst, i16 0, i16 2111  store ptr addrspace(2) %B, ptr addrspace(1) %A112  ret void113}114 115; This should be turned into a constexpr instead of being an instruction116define void @test_overaligned_vec(i8 %B) {117; CHECK-LABEL: @test_overaligned_vec(118; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds nuw (i8, ptr @Global, i64 2), align 1119; CHECK-NEXT:    ret void120;121  %A = getelementptr <2 x half>, ptr @Global, i64 0, i64 1122  store i8 %B, ptr %A123  ret void124}125 126define ptr @test7(ptr %I, i64 %C, i64 %D) {127; CHECK-LABEL: @test7(128; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[C:%.*]]129; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[A]], i64 [[D:%.*]]130; CHECK-NEXT:    ret ptr [[B]]131;132  %A = getelementptr i32, ptr %I, i64 %C133  %B = getelementptr i32, ptr %A, i64 %D134  ret ptr %B135}136 137define ptr @test8(ptr %X) {138        ;; Fold into the cast.139; CHECK-LABEL: @test8(140; CHECK-NEXT:    ret ptr [[X:%.*]]141;142  ret ptr %X143}144 145define i32 @test9() {146; CHECK-LABEL: @test9(147; CHECK-NEXT:    ret i32 8148;149  %A = getelementptr { i32, double }, ptr null, i32 0, i32 1150  %B = ptrtoint ptr %A to i32151  ret i32 %B152}153 154define i1 @test10(ptr %x, ptr %y) {155; CHECK-LABEL: @test10(156; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[X:%.*]], [[Y:%.*]]157; CHECK-NEXT:    ret i1 [[T4]]158;159  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1160  %t3 = getelementptr { i32, i32 }, ptr %y, i32 0, i32 1161  %t4 = icmp eq ptr %t1, %t3162  ret i1 %t4163}164 165define i1 @test10_addrspacecast(ptr %x, ptr addrspace(3) %y) {166; CHECK-LABEL: @test10_addrspacecast(167; CHECK-NEXT:    [[T1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 4168; CHECK-NEXT:    [[T3:%.*]] = getelementptr i8, ptr addrspace(3) [[Y:%.*]], i64 4169; CHECK-NEXT:    [[T3_C:%.*]] = addrspacecast ptr addrspace(3) [[T3]] to ptr170; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[T1]], [[T3_C]]171; CHECK-NEXT:    ret i1 [[T4]]172;173  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1174  %t3 = getelementptr { i32, i32 }, ptr addrspace(3) %y, i32 0, i32 1175  %t3.c = addrspacecast ptr addrspace(3) %t3 to ptr176  %t4 = icmp eq ptr %t1, %t3.c177  ret i1 %t4178}179 180define i1 @test11(ptr %X) {181; CHECK-LABEL: @test11(182; CHECK-NEXT:    [[Q:%.*]] = icmp eq ptr [[X:%.*]], null183; CHECK-NEXT:    ret i1 [[Q]]184;185  %P = getelementptr { i32, i32 }, ptr %X, i32 0, i32 0186  %Q = icmp eq ptr %P, null187  ret i1 %Q188}189 190 191; PR4748192define i32 @test12(ptr %a) {193; CHECK-LABEL: @test12(194; CHECK-NEXT:  entry:195; CHECK-NEXT:    [[G3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8196; CHECK-NEXT:    store i32 10, ptr [[G3]], align 4197; CHECK-NEXT:    ret i32 10198;199entry:200  %g3 = getelementptr %struct.A, ptr %a, i32 0, i32 1201  store i32 10, ptr %g3, align 4202 203 204 205  %g5 = getelementptr %struct.A, ptr %a, i32 0, i32 1206  %a_a = load i32, ptr %g5, align 4207  ret i32 %a_a208}209 210 211; PR2235212%S = type { i32, [ 100 x i32] }213define i1 @test13(i64 %X, ptr %P) {214; CHECK-LABEL: @test13(215; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[X:%.*]], -1216; CHECK-NEXT:    ret i1 [[C]]217;218  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i64 %X219  %C = icmp eq ptr %A, %P220  ret i1 %C221}222 223define <2 x i1> @test13_vector(<2 x i64> %X, <2 x ptr> %P) nounwind {224; CHECK-LABEL: @test13_vector(225; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[X:%.*]], splat (i64 -1)226; CHECK-NEXT:    ret <2 x i1> [[C]]227;228  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i64> %X229  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>230  %C = icmp eq <2 x ptr> %A, %B231  ret <2 x i1> %C232}233 234define <2 x i1> @test13_vector2(i64 %X, <2 x ptr> %P) nounwind {235; CHECK-LABEL: @test13_vector2(236; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0237; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>238; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], <i64 -4, i64 poison>239; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer240; CHECK-NEXT:    ret <2 x i1> [[C]]241;242  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X243  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>244  %C = icmp eq <2 x ptr> %A, %B245  ret <2 x i1> %C246}247 248define <2 x i1> @test13_fixed_fixed(i64 %X, ptr %P, <2 x i64> %y) nounwind {249; CHECK-LABEL: @test13_fixed_fixed(250; CHECK-NEXT:    [[A1:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[X:%.*]]251; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x ptr> poison, ptr [[A1]], i64 0252; CHECK-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <2 x ptr> [[DOTSPLATINSERT]], <2 x ptr> poison, <2 x i32> zeroinitializer253; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds <2 x i64>, ptr [[P]], <2 x i64> [[Y:%.*]]254; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x ptr> [[DOTSPLAT]], [[B]]255; CHECK-NEXT:    ret <2 x i1> [[C]]256;257  %A = getelementptr inbounds <2 x i64>, ptr %P, <2 x i64> zeroinitializer, i64 %X258  %B = getelementptr inbounds <2 x i64>, ptr %P, <2 x i64> %y259  %C = icmp eq <2 x ptr> %A, %B260  ret <2 x i1> %C261}262 263define <2 x i1> @test13_fixed_scalable(i64 %X, ptr %P, <2 x i64> %y) nounwind {264; CHECK-LABEL: @test13_fixed_scalable(265; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0266; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 3, i64 0>267; CHECK-NEXT:    [[A_IDX:%.*]] = shufflevector <2 x i64> [[TMP1]], <2 x i64> poison, <2 x i32> zeroinitializer268; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()269; CHECK-NEXT:    [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 4270; CHECK-NEXT:    [[DOTSPLATINSERT1:%.*]] = insertelement <2 x i64> poison, i64 [[TMP3]], i64 0271; CHECK-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT1]], <2 x i64> poison, <2 x i32> zeroinitializer272; CHECK-NEXT:    [[B_IDX:%.*]] = mul nsw <2 x i64> [[Y:%.*]], [[DOTSPLAT]]273; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[A_IDX]], [[B_IDX]]274; CHECK-NEXT:    ret <2 x i1> [[C]]275;276  %A = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <2 x i64> zeroinitializer, i64 %X277  %B = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <2 x i64> %y278  %C = icmp eq <2 x ptr> %A, %B279  ret <2 x i1> %C280}281 282define <vscale x 2 x i1> @test13_scalable_scalable(i64 %X, ptr %P, <vscale x 2 x i64> %y) nounwind {283; CHECK-LABEL: @test13_scalable_scalable(284; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[X:%.*]], i64 0285; CHECK-NEXT:    [[TMP3:%.*]] = shl nsw <vscale x 2 x i64> [[DOTSPLATINSERT]], splat (i64 3)286; CHECK-NEXT:    [[A_IDX:%.*]] = shufflevector <vscale x 2 x i64> [[TMP3]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer287; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vscale.i64()288; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[TMP1]], 4289; CHECK-NEXT:    [[DOTSPLATINSERT1:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[TMP2]], i64 0290; CHECK-NEXT:    [[DOTSPLAT2:%.*]] = shufflevector <vscale x 2 x i64> [[DOTSPLATINSERT1]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer291; CHECK-NEXT:    [[B_IDX:%.*]] = mul nsw <vscale x 2 x i64> [[Y:%.*]], [[DOTSPLAT2]]292; CHECK-NEXT:    [[C:%.*]] = icmp eq <vscale x 2 x i64> [[A_IDX]], [[B_IDX]]293; CHECK-NEXT:    ret <vscale x 2 x i1> [[C]]294;295  %A = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <vscale x 2 x i64> zeroinitializer, i64 %X296  %B = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <vscale x 2 x i64> %y297  %C = icmp eq <vscale x 2 x ptr> %A, %B298  ret <vscale x 2 x i1> %C299}300 301; This is a test of icmp + shl nuw in disguise - 4611... is 0x3fff...302define <2 x i1> @test13_vector3(i64 %X, <2 x ptr> %P) nounwind {303; CHECK-LABEL: @test13_vector3(304; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0305; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>306; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], <i64 4, i64 poison>307; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer308; CHECK-NEXT:    ret <2 x i1> [[C]]309;310  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X311  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 1, i32 1>, i64 1312  %C = icmp eq <2 x ptr> %A, %B313  ret <2 x i1> %C314}315 316define i1 @test13_as1(i16 %X, ptr addrspace(1) %P) {317; CHECK-LABEL: @test13_as1(318; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1319; CHECK-NEXT:    ret i1 [[C]]320;321  %A = getelementptr inbounds %S, ptr addrspace(1) %P, i16 0, i32 1, i16 %X322  %C = icmp eq ptr addrspace(1) %A, %P323  ret i1 %C324}325 326define <2 x i1> @test13_vector_as1(<2 x i16> %X, <2 x ptr addrspace(1)> %P) {327; CHECK-LABEL: @test13_vector_as1(328; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i16> [[X:%.*]], splat (i16 -1)329; CHECK-NEXT:    ret <2 x i1> [[C]]330;331  %A = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 1, i32 1>, <2 x i16> %X332  %B = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 0, i32 0>333  %C = icmp eq <2 x ptr addrspace(1)> %A, %B334  ret <2 x i1> %C335}336 337define i1 @test13_i32(i32 %X, ptr %P) {338; CHECK-LABEL: @test13_i32(339; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], -1340; CHECK-NEXT:    ret i1 [[C]]341;342  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i32 %X343  %C = icmp eq ptr %A, %P344  ret i1 %C345}346 347define i1 @test13_i16(i16 %X, ptr %P) {348; CHECK-LABEL: @test13_i16(349; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1350; CHECK-NEXT:    ret i1 [[C]]351;352  %A = getelementptr inbounds %S, ptr %P, i16 0, i32 1, i16 %X353  %C = icmp eq ptr %A, %P354  ret i1 %C355}356 357define i1 @test13_i128(i128 %X, ptr %P) {358; CHECK-LABEL: @test13_i128(359; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i128 [[X:%.*]] to i64360; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[TMP1]], -1361; CHECK-NEXT:    ret i1 [[C]]362;363  %A = getelementptr inbounds %S, ptr %P, i128 0, i32 1, i128 %X364  %C = icmp eq ptr %A, %P365  ret i1 %C366}367 368 369@G = external global [3 x i8]370define ptr @test14(i32 %idx) {371; CHECK-LABEL: @test14(372; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[IDX:%.*]] to i64373; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr @G, i64 [[ZEXT]]374; CHECK-NEXT:    ret ptr [[T]]375;376  %zext = zext i32 %idx to i64377  %t = getelementptr i8, ptr @G, i64 %zext378  ret ptr %t379}380 381 382; Test folding of constantexpr geps into normal geps.383@Array = external global [40 x i32]384define ptr @test15(i64 %X) {385; CHECK-LABEL: @test15(386; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr @Array, i64 [[X:%.*]]387; CHECK-NEXT:    ret ptr [[A]]388;389  %A = getelementptr i32, ptr @Array, i64 %X390  ret ptr %A391}392 393define ptr @test_index_canon(ptr %X, i32 %Idx) {394; CHECK-LABEL: @test_index_canon(395; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64396; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[X:%.*]], i64 [[TMP1]]397; CHECK-NEXT:    ret ptr [[R]]398;399  %R = getelementptr i32, ptr %X, i32 %Idx400  ret ptr %R401}402 403define ptr @test_index_canon_inbounds(ptr %X, i32 %Idx) {404; CHECK-LABEL: @test_index_canon_inbounds(405; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64406; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[TMP1]]407; CHECK-NEXT:    ret ptr [[R]]408;409  %R = getelementptr inbounds i32, ptr %X, i32 %Idx410  ret ptr %R411}412 413define ptr @test_index_canon_nusw_nuw(ptr %X, i32 %Idx) {414; CHECK-LABEL: @test_index_canon_nusw_nuw(415; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[IDX:%.*]] to i64416; CHECK-NEXT:    [[R:%.*]] = getelementptr nusw nuw i32, ptr [[X:%.*]], i64 [[TMP1]]417; CHECK-NEXT:    ret ptr [[R]]418;419  %R = getelementptr nusw nuw i32, ptr %X, i32 %Idx420  ret ptr %R421}422 423define ptr @test_index_canon_const_expr_inbounds() {424; CHECK-LABEL: @test_index_canon_const_expr_inbounds(425; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @Global, i64 123)426;427  ret ptr getelementptr inbounds (i8, ptr @Global, i32 123)428}429 430define ptr @test_index_canon_const_expr_nuw_nusw() {431; CHECK-LABEL: @test_index_canon_const_expr_nuw_nusw(432; CHECK-NEXT:    ret ptr getelementptr nusw nuw (i8, ptr @Global, i64 123)433;434  ret ptr getelementptr nusw nuw (i8, ptr @Global, i32 123)435}436 437define ptr @test_const_gep_gep_nuw() {438; CHECK-LABEL: @test_const_gep_gep_nuw(439; CHECK-NEXT:    ret ptr getelementptr nuw (i8, ptr @Global, i64 246)440;441  ret ptr getelementptr nuw (i8, ptr getelementptr nuw (i8, ptr @Global, i64 123), i64 123)442}443 444define ptr @test_const_gep_gep_nusw_no_overflow() {445; CHECK-LABEL: @test_const_gep_gep_nusw_no_overflow(446; CHECK-NEXT:    ret ptr getelementptr nusw nuw (i8, ptr @Global, i64 246)447;448  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 123), i64 123)449}450 451define ptr @test_const_gep_gep_nusw_no_overflow_neg() {452; CHECK-LABEL: @test_const_gep_gep_nusw_no_overflow_neg(453; CHECK-NEXT:    ret ptr getelementptr nusw (i8, ptr @Global, i64 -246)454;455  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 -123), i64 -123)456}457 458define ptr @test_const_gep_gep_nusw_overflow() {459; CHECK-LABEL: @test_const_gep_gep_nusw_overflow(460; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @Global, i64 -2)461;462  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 u0x7fffffffffffffff), i64 u0x7fffffffffffffff)463}464 465define i1 @test17(ptr %P, i32 %I, i32 %J) {466; CHECK-LABEL: @test17(467; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], [[J:%.*]]468; CHECK-NEXT:    ret i1 [[C]]469;470  %X = getelementptr inbounds i16, ptr %P, i32 %I471  %Y = getelementptr inbounds i16, ptr %P, i32 %J472  %C = icmp ult ptr %X, %Y473  ret i1 %C474}475 476define i1 @test18(ptr %P, i32 %I) {477; CHECK-LABEL: @test18(478; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], 0479; CHECK-NEXT:    ret i1 [[C]]480;481  %X = getelementptr inbounds i16, ptr %P, i32 %I482  %C = icmp ult ptr %X, %P483  ret i1 %C484}485 486; Larger than the pointer size for a non-zero address space487define i1 @test18_as1(ptr addrspace(1) %P, i32 %I) {488; CHECK-LABEL: @test18_as1(489; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768490; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0491; CHECK-NEXT:    ret i1 [[C]]492;493  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I494  %C = icmp ult ptr addrspace(1) %X, %P495  ret i1 %C496}497 498; Smaller than the pointer size for a non-zero address space499define i1 @test18_as1_i32(ptr addrspace(1) %P, i32 %I) {500; CHECK-LABEL: @test18_as1_i32(501; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768502; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0503; CHECK-NEXT:    ret i1 [[C]]504;505  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I506  %C = icmp ult ptr addrspace(1) %X, %P507  ret i1 %C508}509 510; Smaller than pointer size511define i1 @test18_i16(ptr %P, i16 %I) {512; CHECK-LABEL: @test18_i16(513; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[I:%.*]], 0514; CHECK-NEXT:    ret i1 [[C]]515;516  %X = getelementptr inbounds i16, ptr %P, i16 %I517  %C = icmp ult ptr %X, %P518  ret i1 %C519}520 521; Same as pointer size522define i1 @test18_i64(ptr %P, i64 %I) {523; CHECK-LABEL: @test18_i64(524; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[I:%.*]], 0525; CHECK-NEXT:    ret i1 [[C]]526;527  %X = getelementptr inbounds i16, ptr %P, i64 %I528  %C = icmp ult ptr %X, %P529  ret i1 %C530}531 532; Larger than the pointer size533define i1 @test18_i128(ptr %P, i128 %I) {534; CHECK-LABEL: @test18_i128(535; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[I:%.*]], 9223372036854775808536; CHECK-NEXT:    [[C:%.*]] = icmp ne i128 [[TMP1]], 0537; CHECK-NEXT:    ret i1 [[C]]538;539  %X = getelementptr inbounds i16, ptr %P, i128 %I540  %C = icmp ult ptr %X, %P541  ret i1 %C542}543 544define i32 @test19(ptr %P, i32 %A, i32 %B) {545; CHECK-LABEL: @test19(546; CHECK-NEXT:    [[T10:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]547; CHECK-NEXT:    [[T11:%.*]] = zext i1 [[T10]] to i32548; CHECK-NEXT:    ret i32 [[T11]]549;550  %t4 = getelementptr inbounds i32, ptr %P, i32 %A551  %t9 = getelementptr inbounds i32, ptr %P, i32 %B552  %t10 = icmp eq ptr %t4, %t9553  %t11 = zext i1 %t10 to i32554  ret i32 %t11555}556 557define i32 @test20(ptr %P, i32 %A, i32 %B) {558; CHECK-LABEL: @test20(559; CHECK-NEXT:    [[T6:%.*]] = icmp eq i32 [[A:%.*]], 0560; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32561; CHECK-NEXT:    ret i32 [[T7]]562;563  %t4 = getelementptr inbounds i32, ptr %P, i32 %A564  %t6 = icmp eq ptr %t4, %P565  %t7 = zext i1 %t6 to i32566  ret i32 %t7567}568 569define i32 @test20_as1(ptr addrspace(1) %P, i32 %A, i32 %B) {570; CHECK-LABEL: @test20_as1(571; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i32 [[A:%.*]] to i16572; CHECK-NEXT:    [[T6:%.*]] = icmp eq i16 [[TMP1]], 0573; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32574; CHECK-NEXT:    ret i32 [[T7]]575;576  %t4 = getelementptr inbounds i32, ptr addrspace(1) %P, i32 %A577  %t6 = icmp eq ptr addrspace(1) %t4, %P578  %t7 = zext i1 %t6 to i32579  ret i32 %t7580}581 582 583define i32 @test21(ptr %pbob1) {584; CHECK-LABEL: @test21(585; CHECK-NEXT:    [[RVAL:%.*]] = load i32, ptr [[PBOB1:%.*]], align 4586; CHECK-NEXT:    ret i32 [[RVAL]]587;588  %pbob2 = getelementptr %intstruct, ptr %pbob1589  %rval = load i32, ptr %pbob2590  ret i32 %rval591}592 593 594@A = global i32 1                 ; <ptr> [#uses=1]595@B = global i32 2                 ; <ptr> [#uses=1]596 597define i1 @test22() {598; CHECK-LABEL: @test22(599; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr getelementptr inbounds nuw (i8, ptr @A, i64 4), getelementptr (i8, ptr @B, i64 8)600; CHECK-NEXT:    ret i1 [[C]]601;602  %C = icmp ult ptr getelementptr (i32, ptr @A, i64 1),603  getelementptr (i32, ptr @B, i64 2)604  ret i1 %C605}606 607 608%X = type { [10 x i32], float }609 610define i1 @test23() {611; CHECK-LABEL: @test23(612; CHECK-NEXT:    ret i1 false613;614  %A = getelementptr %X, ptr null, i64 0, i32 0, i64 0                  ; <ptr> [#uses=1]615  %B = icmp ne ptr %A, null                ; <i1> [#uses=1]616  ret i1 %B617}618 619define void @test25() {620; CHECK-LABEL: @test25(621; CHECK-NEXT:  entry:622; CHECK-NEXT:    unreachable623;624entry:625  %t = getelementptr { i64, i64, i64, i64 }, ptr null, i32 0, i32 3626  %t.upgrd.1 = load i64, ptr %t627  %t8.ui = load i64, ptr null628  %t8 = bitcast i64 %t8.ui to i64629  %t9 = and i64 %t8, %t.upgrd.1630  %sext = trunc i64 %t9 to i32631  %t27.i = sext i32 %sext to i64632  tail call void @foo25( i32 0, i64 %t27.i )633  unreachable634}635 636declare void @foo25(i32, i64)637 638 639; PR1637640define i1 @test26(ptr %arr) {641; CHECK-LABEL: @test26(642; CHECK-NEXT:    ret i1 true643;644  %X = getelementptr i8, ptr %arr, i32 1645  %Y = getelementptr i8, ptr %arr, i32 1646  %test = icmp uge ptr %X, %Y647  ret i1 %test648}649 650  %struct.__large_struct = type { [100 x i64] }651  %struct.compat_siginfo = type { i32, i32, i32, { [29 x i32] } }652  %struct.siginfo_t = type { i32, i32, i32, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] } }653  %struct.sigval_t = type { ptr }654 655define i32 @test27(ptr %to, ptr %from, ptr %from_addr) {656; CHECK-LABEL: @test27(657; CHECK-NEXT:  entry:658; CHECK-NEXT:    [[T344:%.*]] = load ptr, ptr [[FROM_ADDR:%.*]], align 8659; CHECK-NEXT:    [[T348:%.*]] = getelementptr i8, ptr [[T344]], i64 24660; CHECK-NEXT:    [[T351:%.*]] = load i32, ptr [[T348]], align 8661; CHECK-NEXT:    [[T360:%.*]] = call i32 asm sideeffect "...", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"(i32 [[T351]], ptr elementtype([[STRUCT___LARGE_STRUCT:%.*]]) null, i32 -14, i32 0) #[[ATTR0:[0-9]+]]662; CHECK-NEXT:    unreachable663;664entry:665  %t344 = load ptr, ptr %from_addr, align 8666  %t345 = getelementptr %struct.siginfo_t, ptr %t344, i32 0, i32 3667  %t346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }, ptr %t345, i32 0, i32 0668  %t348 = getelementptr { i32, i32, %struct.sigval_t }, ptr %t346, i32 0, i32 2669  %t351 = load i32, ptr %t348, align 8670  %t360 = call i32 asm sideeffect "...",671  "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %t351, ptr elementtype(%struct.__large_struct) null, i32 -14, i32 0 )672  unreachable673}674 675; PR1978676  %struct.x = type <{ i8 }>677@.str = internal constant [6 x i8] c"Main!\00"678@.str1 = internal constant [12 x i8] c"destroy %p\0A\00"679 680define i32 @test28() nounwind  {681; CHECK-LABEL: @test28(682; CHECK-NEXT:  entry:683; CHECK-NEXT:    [[ORIENTATIONS:%.*]] = alloca [1 x [1 x %struct.x]], align 8684; CHECK-NEXT:    [[T3:%.*]] = call i32 @puts(ptr noundef nonnull dereferenceable(1) @.str) #[[ATTR0]]685; CHECK-NEXT:    br label [[BB10:%.*]]686; CHECK:       bb10:687; CHECK-NEXT:    [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[BB10]] ]688; CHECK-NEXT:    [[T12_REC:%.*]] = xor i32 [[INDVAR]], -1689; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[T12_REC]] to i64690; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], 1691; CHECK-NEXT:    [[T12:%.*]] = getelementptr inbounds i8, ptr [[ORIENTATIONS]], i64 [[TMP1]]692; CHECK-NEXT:    [[T16:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str1, ptr nonnull [[T12]]) #[[ATTR0]]693; CHECK-NEXT:    [[T84:%.*]] = icmp eq i64 [[TMP1]], 0694; CHECK-NEXT:    [[INDVAR_NEXT]] = add i32 [[INDVAR]], 1695; CHECK-NEXT:    br i1 [[T84]], label [[BB17:%.*]], label [[BB10]]696; CHECK:       bb17:697; CHECK-NEXT:    ret i32 0698;699entry:700  %orientations = alloca [1 x [1 x %struct.x]]701  %t3 = call i32 @puts( ptr @.str ) nounwind702  %t45 = getelementptr inbounds [1 x [1 x %struct.x]], ptr %orientations, i32 1, i32 0, i32 0703  br label %bb10704 705bb10:706  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb10 ]707  %t.0.reg2mem.0.rec = mul i32 %indvar, -1708  %t12.rec = add i32 %t.0.reg2mem.0.rec, -1709  %t12 = getelementptr inbounds %struct.x, ptr %t45, i32 %t12.rec710  %t16 = call i32 (ptr, ...) @printf( ptr nonnull dereferenceable(1) @.str1, ptr %t12 ) nounwind711  %t84 = icmp eq ptr %t12, %orientations712  %indvar.next = add i32 %indvar, 1713  br i1 %t84, label %bb17, label %bb10714 715bb17:716  ret i32 0717}718 719declare i32 @puts(ptr)720 721declare i32 @printf(ptr, ...)722 723 724 725 726; rdar://6762290727  %T = type <{ i64, i64, i64 }>728define i32 @test29(ptr %start, i32 %X) nounwind {729; CHECK-LABEL: @test29(730; CHECK-NEXT:  entry:731; CHECK-NEXT:    store i1 true, ptr poison, align 1732; CHECK-NEXT:    br i1 poison, label [[IF_THEN216:%.*]], label [[IF_END363:%.*]]733; CHECK:       if.then216:734; CHECK-NEXT:    ret i32 1735; CHECK:       if.end363:736; CHECK-NEXT:    ret i32 0737;738entry:739  %t3 = load i64, ptr null740  %add.ptr = getelementptr i8, ptr %start, i64 %t3741  %t158 = load i32, ptr null742  %add.ptr159 = getelementptr %T, ptr null, i32 %t158743  %add.ptr212 = getelementptr i8, ptr %start, i32 %X744  %cmp214 = icmp ugt ptr %add.ptr212, %add.ptr745  br i1 %cmp214, label %if.then216, label %if.end363746 747if.then216:748  ret i32 1749 750if.end363:751  ret i32 0752}753 754 755; PR3694756define i32 @test30(i32 %m, i32 %n) nounwind {757; CHECK-LABEL: @test30(758; CHECK-NEXT:  entry:759; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N:%.*]] to i64760; CHECK-NEXT:    [[TMP1:%.*]] = alloca i32, i64 [[TMP0]], align 4761; CHECK-NEXT:    call void @test30f(ptr nonnull [[TMP1]]) #[[ATTR0]]762; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[M:%.*]] to i64763; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[TMP2]]764; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4765; CHECK-NEXT:    ret i32 [[TMP4]]766;767entry:768  %0 = alloca i32, i32 %n, align 4769  call void @test30f(ptr %0) nounwind770  %1 = getelementptr [0 x i32], ptr %0, i32 0, i32 %m771  %2 = load i32, ptr %1, align 4772  ret i32 %2773}774 775declare void @test30f(ptr)776 777 778 779define i1 @test31(ptr %A) {780; CHECK-LABEL: @test31(781; CHECK-NEXT:    ret i1 true782;783  %B = getelementptr i32, ptr %A, i32 1784  %C = getelementptr i32, ptr %A, i64 1785  %V = icmp eq ptr %B, %C786  ret i1 %V787}788 789 790; PR1345791define ptr @test32(ptr %v) {792; CHECK-LABEL: @test32(793; CHECK-NEXT:    [[A:%.*]] = alloca [4 x ptr], align 16794; CHECK-NEXT:    store ptr null, ptr [[A]], align 8795; CHECK-NEXT:    [[D:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 8796; CHECK-NEXT:    store ptr [[V:%.*]], ptr [[D]], align 8797; CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 16798; CHECK-NEXT:    [[G:%.*]] = load ptr, ptr [[F]], align 8799; CHECK-NEXT:    ret ptr [[G]]800;801  %A = alloca [4 x ptr], align 16802  store ptr null, ptr %A803  %D = getelementptr { [16 x i8] }, ptr %A, i32 0, i32 0, i32 8804  store ptr %v, ptr %D805  %F = getelementptr [4 x ptr], ptr %A, i32 0, i32 2806  %G = load ptr, ptr %F807  ret ptr %G808}809 810; PR3290811%struct.Key = type { { i32, i32 } }812%struct.anon = type <{ i8, [3 x i8], i32 }>813 814define ptr @test33(ptr %A) {815; CHECK-LABEL: @test33(816; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4817; CHECK-NEXT:    ret ptr [[C]]818;819  %C = getelementptr %struct.anon, ptr %A, i32 0, i32 2820  ret ptr %C821}822 823define ptr addrspace(1) @test33_as1(ptr addrspace(1) %A) {824; CHECK-LABEL: @test33_as1(825; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 4826; CHECK-NEXT:    ret ptr addrspace(1) [[C]]827;828  %C = getelementptr %struct.anon, ptr addrspace(1) %A, i32 0, i32 2829  ret ptr addrspace(1) %C830}831 832define ptr addrspace(1) @test33_array_as1(ptr addrspace(1) %A) {833; CHECK-LABEL: @test33_array_as1(834; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 8835; CHECK-NEXT:    ret ptr addrspace(1) [[C]]836;837  %C = getelementptr [5 x i32], ptr addrspace(1) %A, i32 0, i32 2838  ret ptr addrspace(1) %C839}840 841; Make sure the GEP indices use the right pointer sized integer842define ptr addrspace(1) @test33_array_struct_as1(ptr addrspace(1) %A) {843; CHECK-LABEL: @test33_array_struct_as1(844; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 8845; CHECK-NEXT:    ret ptr addrspace(1) [[C]]846;847  %C = getelementptr [20 x i32], ptr addrspace(1) %A, i32 0, i32 2848  ret ptr addrspace(1) %C849}850 851define ptr addrspace(1) @test33_addrspacecast(ptr %A) {852; CHECK-LABEL: @test33_addrspacecast(853; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)854; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[B]], i16 4855; CHECK-NEXT:    ret ptr addrspace(1) [[C]]856;857  %B = addrspacecast ptr %A to ptr addrspace(1)858  %C = getelementptr %struct.anon, ptr addrspace(1) %B, i32 0, i32 2859  ret ptr addrspace(1) %C860}861 862  %T2 = type { ptr, i8 }863define ptr @test34(ptr %Val, i64 %V) nounwind {864; CHECK-LABEL: @test34(865; CHECK-NEXT:  entry:866; CHECK-NEXT:    [[C_CAST:%.*]] = inttoptr i64 [[V:%.*]] to ptr867; CHECK-NEXT:    ret ptr [[C_CAST]]868;869entry:870  %A = alloca %T2, align 8871 872  store i64 %V, ptr %A873  %C = load ptr, ptr %A, align 8874  ret ptr %C875}876 877%t0 = type { ptr, [19 x i8] }878%t1 = type { ptr, [0 x i8] }879 880@array = external global [11 x i8]881 882@s = external global %t0883@"\01LC8" = external constant [17 x i8]884 885; Instcombine should be able to fold this getelementptr.886 887define i32 @test35() nounwind {888; CHECK-LABEL: @test35(889; CHECK-NEXT:    [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @"\01LC8", ptr nonnull getelementptr inbounds nuw (i8, ptr @s, i64 8)) #[[ATTR0]]890; CHECK-NEXT:    ret i32 0891;892  call i32 (ptr, ...) @printf(ptr @"\01LC8",893  ptr getelementptr (%t1, ptr @s, i32 0, i32 1, i32 0)) nounwind894  ret i32 0895}896 897; Don't treat signed offsets as unsigned.898define ptr @test36() nounwind {899; CHECK-LABEL: @test36(900; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @array, i64 -1)901;902  ret ptr getelementptr ([11 x i8], ptr @array, i32 0, i64 -1)903}904 905; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0).906@A37 = external constant [1 x i8]907define i1 @test37() nounwind {908; CHECK-LABEL: @test37(909; CHECK-NEXT:    ret i1 true910;911  %t = icmp eq ptr getelementptr ([1 x i8], ptr @A37, i64 0, i64 1),912  getelementptr ([1 x i8], ptr @A37, i64 1, i64 0)913  ret i1 %t914}915 916; Test index promotion917define ptr @test38(ptr %I, i32 %n) {918; CHECK-LABEL: @test38(919; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N:%.*]] to i64920; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[TMP1]]921; CHECK-NEXT:    ret ptr [[A]]922;923  %A = getelementptr i32, ptr %I, i32 %n924  ret ptr %A925}926 927; Test that we don't duplicate work when the second gep is a "bitcast".928%pr10322_t = type { ptr }929declare void @pr10322_f2(ptr)930declare void @pr10322_f3(ptr)931define void @pr10322_f1(ptr %foo) {932; CHECK-LABEL: @pr10322_f1(933; CHECK-NEXT:  entry:934; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO:%.*]], i64 16935; CHECK-NEXT:    call void @pr10322_f2(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]936; CHECK-NEXT:    call void @pr10322_f3(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]937; CHECK-NEXT:    ret void938;939entry:940  %arrayidx8 = getelementptr inbounds %pr10322_t, ptr %foo, i64 2941  call void @pr10322_f2(ptr %arrayidx8) nounwind942  call void @pr10322_f3(ptr %arrayidx8) nounwind943  ret void944 945}946 947; Test that we combine the last two geps in this sequence, before we948; would wait for gep1 and gep2 to be combined and never combine 2 and 3.949%three_gep_t = type {i32}950%three_gep_t2 = type {%three_gep_t}951 952define void @three_gep_f(ptr %x) {953; CHECK-LABEL: @three_gep_f(954; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 8955; CHECK-NEXT:    call void @three_gep_h(ptr [[GEP1]])956; CHECK-NEXT:    call void @three_gep_g(ptr [[GEP1]])957; CHECK-NEXT:    ret void958;959  %gep1 = getelementptr %three_gep_t2, ptr %x, i64 2960  call void @three_gep_h(ptr %gep1)961  call void @three_gep_g(ptr %gep1)962 963  ret void964}965 966declare void @three_gep_g(ptr)967declare void @three_gep_h(ptr)968 969%struct.ham = type { i32, ptr, ptr, ptr }970%struct.zot = type { i64, i8 }971 972define void @test39(ptr %arg, i8 %arg1) nounwind {973; CHECK-LABEL: @test39(974; CHECK-NEXT:    [[T:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG:%.*]], i64 16975; CHECK-NEXT:    [[T2:%.*]] = load ptr, ptr [[T]], align 8976; CHECK-NEXT:    [[T4:%.*]] = getelementptr inbounds i8, ptr [[T2]], i64 -8977; CHECK-NEXT:    store i8 [[ARG1:%.*]], ptr [[T4]], align 8978; CHECK-NEXT:    ret void979;980  %t = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 2981  %t2 = load ptr, ptr %t, align 8982  %t4 = getelementptr inbounds i8, ptr %t2, i64 -8983  store i8 %arg1, ptr %t4, align 8984  ret void985 986}987 988define i1 @pr16483(ptr %a, ptr %b) {989; CHECK-LABEL: @pr16483(990; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]]991; CHECK-NEXT:    ret i1 [[CMP]]992;993  %cmp = icmp ult ptr %a, %b994  ret i1 %cmp995 996}997 998define i8 @test_gep_bitcast_as1(ptr addrspace(1) %arr, i16 %N) {999; CHECK-LABEL: @test_gep_bitcast_as1(1000; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 21001; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]1002; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 11003; CHECK-NEXT:    ret i8 [[X]]1004;1005  %V = mul i16 %N, 41006  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V1007  %x = load i8, ptr addrspace(1) %t1008  ret i8 %x1009}1010 1011; The element size of the array matches the element size of the pointer1012define i64 @test_gep_bitcast_array_same_size_element(ptr %arr, i64 %N) {1013; CHECK-LABEL: @test_gep_bitcast_array_same_size_element(1014; CHECK-NEXT:    [[T_IDX:%.*]] = shl i64 [[N:%.*]], 61015; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr [[ARR:%.*]], i64 [[T_IDX]]1016; CHECK-NEXT:    [[X:%.*]] = load i64, ptr [[T]], align 41017; CHECK-NEXT:    ret i64 [[X]]1018;1019  %V = mul i64 %N, 81020  %t = getelementptr i64, ptr %arr, i64 %V1021  %x = load i64, ptr %t1022  ret i64 %x1023}1024 1025; gep should be done in the original address space.1026define i64 @test_gep_bitcast_array_same_size_element_addrspacecast(ptr %arr, i64 %N) {1027; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast(1028; CHECK-NEXT:    [[CAST:%.*]] = addrspacecast ptr [[ARR:%.*]] to ptr addrspace(3)1029; CHECK-NEXT:    [[T_IDX:%.*]] = shl i64 [[N:%.*]], 61030; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(3) [[CAST]], i64 [[T_IDX]]1031; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(3) [[T]], align 41032; CHECK-NEXT:    ret i64 [[X]]1033;1034  %cast = addrspacecast ptr %arr to ptr addrspace(3)1035  %V = mul i64 %N, 81036  %t = getelementptr i64, ptr addrspace(3) %cast, i64 %V1037  %x = load i64, ptr addrspace(3) %t1038  ret i64 %x1039}1040 1041; The element size of the array is different the element size of the pointer1042define i8 @test_gep_bitcast_array_different_size_element(ptr %arr, i64 %N) {1043; CHECK-LABEL: @test_gep_bitcast_array_different_size_element(1044; CHECK-NEXT:    [[V:%.*]] = shl i64 [[N:%.*]], 31045; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr [[ARR:%.*]], i64 [[V]]1046; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[T]], align 11047; CHECK-NEXT:    ret i8 [[X]]1048;1049  %V = mul i64 %N, 81050  %t = getelementptr i8, ptr %arr, i64 %V1051  %x = load i8, ptr %t1052  ret i8 %x1053}1054 1055define i64 @test_gep_bitcast_array_same_size_element_as1(ptr addrspace(1) %arr, i16 %N) {1056; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_as1(1057; CHECK-NEXT:    [[T_IDX:%.*]] = shl i16 [[N:%.*]], 61058; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[T_IDX]]1059; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(1) [[T]], align 41060; CHECK-NEXT:    ret i64 [[X]]1061;1062  %V = mul i16 %N, 81063  %t = getelementptr i64, ptr addrspace(1) %arr, i16 %V1064  %x = load i64, ptr addrspace(1) %t1065  ret i64 %x1066}1067 1068define i8 @test_gep_bitcast_array_different_size_element_as1(ptr addrspace(1) %arr, i16 %N) {1069; CHECK-LABEL: @test_gep_bitcast_array_different_size_element_as1(1070; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 31071; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]1072; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 11073; CHECK-NEXT:    ret i8 [[X]]1074;1075  %V = mul i16 %N, 81076  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V1077  %x = load i8, ptr addrspace(1) %t1078  ret i8 %x1079}1080 1081define i64 @test40() {1082; CHECK-LABEL: @test40(1083; CHECK-NEXT:    ret i64 81084;1085  %array = alloca [3 x i32], align 41086  %gep = getelementptr inbounds [3 x i32], ptr %array, i64 0, i64 21087  %p = ptrtoint ptr %array to i641088  %np = sub i64 0, %p1089  %gep2 = getelementptr i8, ptr %gep, i64 %np1090  %ret = ptrtoint ptr %gep2 to i641091  ret i64 %ret1092 1093}1094 1095define i16 @test41(ptr addrspace(1) %array) {1096; CHECK-LABEL: @test41(1097; CHECK-NEXT:    ret i16 81098;1099  %gep = getelementptr inbounds [3 x i32], ptr addrspace(1) %array, i16 0, i16 21100  %p = ptrtoint ptr addrspace(1) %array to i161101  %np = sub i16 0, %p1102  %gep2 = getelementptr i8, ptr addrspace(1) %gep, i16 %np1103  %ret = ptrtoint ptr addrspace(1) %gep2 to i161104  ret i16 %ret1105 1106}1107 1108define ptr @test42i(ptr %c1, ptr %c2) {1109; CHECK-LABEL: @test42i(1110; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i641111; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]1112; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C2:%.*]], i64 [[SUB]]1113; CHECK-NEXT:    ret ptr [[GEP]]1114;1115  %ptrtoint = ptrtoint ptr %c1 to i641116  %sub = sub i64 0, %ptrtoint1117  %gep = getelementptr inbounds i8, ptr %c2, i64 %sub1118  ret ptr %gep1119 1120}1121 1122define ptr @test42(ptr %c1, ptr %c2) {1123; CHECK-LABEL: @test42(1124; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i641125; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]1126; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[C2:%.*]], i64 [[SUB]]1127; CHECK-NEXT:    ret ptr [[GEP]]1128;1129  %ptrtoint = ptrtoint ptr %c1 to i641130  %sub = sub i64 0, %ptrtoint1131  %gep = getelementptr i8, ptr %c2, i64 %sub1132  ret ptr %gep1133 1134}1135 1136define ptr @test43i(ptr %c1, ptr %c2) {1137; CHECK-LABEL: @test43i(1138; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i641139; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]1140; CHECK-NEXT:    [[SHR:%.*]] = ashr i64 [[SUB]], 11141; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, ptr [[C2:%.*]], i64 [[SHR]]1142; CHECK-NEXT:    ret ptr [[GEP]]1143;1144  %ptrtoint = ptrtoint ptr %c1 to i641145  %sub = sub i64 0, %ptrtoint1146  %shr = ashr i64 %sub, 11147  %gep = getelementptr inbounds i16, ptr %c2, i64 %shr1148  ret ptr %gep1149 1150}1151 1152define ptr @test44i(ptr %c1, ptr %c2) {1153; CHECK-LABEL: @test44i(1154; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i641155; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]1156; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 71157; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SHR]]1158; CHECK-NEXT:    ret ptr [[GEP]]1159;1160  %ptrtoint = ptrtoint ptr %c1 to i641161  %sub = sub i64 0, %ptrtoint1162  %shr = sdiv i64 %sub, 71163  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %shr1164  ret ptr %gep1165 1166}1167 1168define ptr @test45(ptr %c1, ptr %c2) {1169; CHECK-LABEL: @test45(1170; CHECK-NEXT:    [[PTRTOINT1:%.*]] = ptrtoint ptr [[C1:%.*]] to i641171; CHECK-NEXT:    [[PTRTOINT2:%.*]] = ptrtoint ptr [[C2:%.*]] to i641172; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[PTRTOINT2]], [[PTRTOINT1]]1173; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 71174; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C1]], i64 [[SHR]]1175; CHECK-NEXT:    ret ptr [[GEP]]1176;1177  %ptrtoint1 = ptrtoint ptr %c1 to i641178  %ptrtoint2 = ptrtoint ptr %c2 to i641179  %sub = sub i64 %ptrtoint2, %ptrtoint1   ; C2 - C11180  %shr = sdiv i64 %sub, 71181  %gep = getelementptr inbounds %struct.C, ptr %c1, i64 %shr   ; C1 + (C2 - C1)1182  ret ptr %gep1183}1184 1185define ptr @test46(ptr %c1, ptr %c2, i64 %N) {1186; CHECK-LABEL: @test46(1187; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i641188; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]1189; CHECK-NEXT:    [[SDIV:%.*]] = sdiv i64 [[SUB]], [[N:%.*]]1190; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SDIV]]1191; CHECK-NEXT:    ret ptr [[GEP]]1192;1193  %ptrtoint = ptrtoint ptr %c1 to i641194  %sub = sub i64 0, %ptrtoint1195  %sdiv = sdiv i64 %sub, %N1196  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %sdiv1197  ret ptr %gep1198 1199}1200 1201define ptr @test47(ptr %I, i64 %C, i64 %D) {1202; CHECK-LABEL: @test47(1203; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]1204; CHECK-NEXT:    ret ptr [[B]]1205;1206  %sub = sub i64 %D, %C1207  %A = getelementptr i32, ptr %I, i64 %C1208  %B = getelementptr i32, ptr %A, i64 %sub1209  ret ptr %B1210}1211 1212define ptr @test48(ptr %I, i64 %C, i64 %D) {1213; CHECK-LABEL: @test48(1214; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]1215; CHECK-NEXT:    ret ptr [[B]]1216;1217  %sub = sub i64 %D, %C1218  %A = getelementptr i32, ptr %I, i64 %sub1219  %B = getelementptr i32, ptr %A, i64 %C1220  ret ptr %B1221}1222 1223define ptr @test49(ptr %I, i64 %C) {1224; CHECK-LABEL: @test49(1225; CHECK-NEXT:    [[B:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 -41226; CHECK-NEXT:    ret ptr [[B]]1227;1228  %notC = xor i64 -1, %C1229  %A = getelementptr i32, ptr %I, i64 %C1230  %B = getelementptr i32, ptr %A, i64 %notC1231  ret ptr %B1232}1233 1234define ptr addrspace(1) @ascast_0_gep(ptr %p) nounwind {1235; CHECK-LABEL: @ascast_0_gep(1236; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)1237; CHECK-NEXT:    ret ptr addrspace(1) [[X]]1238;1239  %x = addrspacecast ptr %p to ptr addrspace(1)1240  ret ptr addrspace(1) %x1241}1242 1243; Do not merge the GEP and the addrspacecast, because it would undo the1244; addrspacecast canonicalization.1245define ptr addrspace(1) @ascast_0_0_gep(ptr %p) nounwind {1246; CHECK-LABEL: @ascast_0_0_gep(1247; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)1248; CHECK-NEXT:    ret ptr addrspace(1) [[X]]1249;1250  %x = addrspacecast ptr %p to ptr addrspace(1)1251  ret ptr addrspace(1) %x1252}1253 1254define <2 x ptr> @PR32414(ptr %ptr) {1255; CHECK-LABEL: @PR32414(1256; CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], <2 x i64> <i64 0, i64 1>1257; CHECK-NEXT:    ret <2 x ptr> [[T1]]1258;1259  %t1 = getelementptr inbounds i32, ptr %ptr, <2 x i64> <i64 0, i64 1>1260  ret <2 x ptr> %t11261}1262 1263define ptr @test_bitcast_nzgep(ptr %base, i64 %idx) {1264; CHECK-LABEL: @test_bitcast_nzgep(1265; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]1266; CHECK-NEXT:    ret ptr [[PTR]]1267;1268  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx1269  ret ptr %ptr1270}1271 1272define ptr @test_zgep_nzgep(ptr %base, i64 %idx) {1273; CHECK-LABEL: @test_zgep_nzgep(1274; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]1275; CHECK-NEXT:    ret ptr [[PTR]]1276;1277  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx1278  ret ptr %ptr1279}1280 1281define ptr @test_nzgep_zgep(ptr %base, i64 %idx) {1282; CHECK-LABEL: @test_nzgep_zgep(1283; CHECK-NEXT:    [[BASE2:%.*]] = getelementptr inbounds [1 x i32], ptr [[BASE:%.*]], i64 [[IDX:%.*]]1284; CHECK-NEXT:    ret ptr [[BASE2]]1285;1286  %base2 = getelementptr inbounds [1 x i32], ptr %base, i64 %idx1287  ret ptr %base21288}1289 1290define ptr @test_gep_inbounds_of_gep(ptr %base) {1291; CHECK-LABEL: @test_gep_inbounds_of_gep(1292; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 321293; CHECK-NEXT:    ret ptr [[PTR2]]1294;1295  %ptr1 = getelementptr i32, ptr %base, i64 41296  %ptr2 = getelementptr inbounds i32, ptr %ptr1, i64 41297  ret ptr %ptr21298}1299 1300%struct.f = type { i32 }1301 1302@g0 = internal unnamed_addr constant %struct.f zeroinitializer, align 41303@g1 = internal unnamed_addr constant %struct.f { i32 -1 }, align 41304 1305define ptr @PR45084(i1 %cond) {1306; CHECK-LABEL: @PR45084(1307; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g1, !prof [[PROF0:![0-9]+]]1308; CHECK-NEXT:    ret ptr [[SEL]]1309;1310  %sel = select i1 %cond, ptr @g0, ptr @g1, !prof !01311  ret ptr %sel1312}1313 1314define ptr @PR45084_extra_use(i1 %cond, ptr %p) {1315; CHECK-LABEL: @PR45084_extra_use(1316; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g11317; CHECK-NEXT:    store ptr [[SEL]], ptr [[P:%.*]], align 81318; CHECK-NEXT:    ret ptr [[SEL]]1319;1320  %sel = select i1 %cond, ptr @g0, ptr @g11321  store ptr %sel, ptr %p1322  ret ptr %sel1323}1324 1325define ptr @D98588(ptr %c1, i64 %offset) {1326; CHECK-LABEL: @D98588(1327; CHECK-NEXT:    [[C2_NEXT_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 31328; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C1:%.*]], i64 [[C2_NEXT_IDX]]1329; CHECK-NEXT:    ret ptr [[GEP]]1330;1331  %c2_next = getelementptr inbounds i64, ptr %c1, i64 %offset1332  %ptrtoint1 = ptrtoint ptr %c1 to i641333  %ptrtoint2 = ptrtoint ptr %c2_next to i641334  %sub = sub i64 %ptrtoint2, %ptrtoint1   ; C2 - C11335  %gep = getelementptr inbounds i8, ptr %c1, i64 %sub   ; C1 + (C2 - C1)1336  ret ptr %gep1337}1338 1339declare noalias ptr @malloc(i64) nounwind allockind("alloc,uninitialized") allocsize(0)1340 1341define i32 @test_gep_bitcast_malloc(ptr %a) {1342; CHECK-LABEL: @test_gep_bitcast_malloc(1343; CHECK-NEXT:  entry:1344; CHECK-NEXT:    ret i32 undef1345;1346entry:1347  %call = call noalias ptr @malloc(i64 16) #21348  %g3 = getelementptr %struct.A, ptr %call, i32 0, i32 21349  %a_c = load i32, ptr %g3, align 41350  ret i32 %a_c1351}1352 1353define ptr @gep_of_gep_multiuse_const_and_const(ptr %p, i64 %idx) {1354; CHECK-LABEL: @gep_of_gep_multiuse_const_and_const(1355; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 81356; CHECK-NEXT:    call void @use(ptr [[GEP1]])1357; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 121358; CHECK-NEXT:    ret ptr [[GEP2]]1359;1360  %gep1 = getelementptr { i32, i32 }, ptr %p, i64 11361  call void @use(ptr %gep1)1362  %gep2 = getelementptr { i32, i32 }, ptr %gep1, i64 0, i32 11363  ret ptr %gep21364}1365 1366define ptr @gep_of_gep_multiuse_var_and_const(ptr %p, i64 %idx) {1367; CHECK-LABEL: @gep_of_gep_multiuse_var_and_const(1368; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr { i32, i32 }, ptr [[P:%.*]], i64 [[IDX:%.*]]1369; CHECK-NEXT:    call void @use(ptr [[GEP1]])1370; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 41371; CHECK-NEXT:    ret ptr [[GEP2]]1372;1373  %gep1 = getelementptr { i32, i32 }, ptr %p, i64 %idx1374  call void @use(ptr %gep1)1375  %gep2 = getelementptr { i32, i32 }, ptr %gep1, i64 0, i32 11376  ret ptr %gep21377}1378 1379define ptr @gep_of_gep_multiuse_var_and_var(ptr %p, i64 %idx, i64 %idx2) {1380; CHECK-LABEL: @gep_of_gep_multiuse_var_and_var(1381; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr [4 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]1382; CHECK-NEXT:    call void @use(ptr [[GEP1]])1383; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX2:%.*]]1384; CHECK-NEXT:    ret ptr [[GEP2]]1385;1386  %gep1 = getelementptr [4 x i32], ptr %p, i64 %idx1387  call void @use(ptr %gep1)1388  %gep2 = getelementptr [4 x i32], ptr %gep1, i64 0, i64 %idx21389  ret ptr %gep21390}1391 1392@g_i32_di = global i32 01393@g_i32_e = external global i321394@g_i32_ew = extern_weak global i321395@g_0xi8_e = external global [0 x i8]1396 1397define ptr @const_gep_global_di_i8_smaller() {1398; CHECK-LABEL: @const_gep_global_di_i8_smaller(1399; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_di, i64 3)1400;1401  ret ptr getelementptr (i8, ptr @g_i32_di, i64 3)1402}1403 1404define ptr @const_gep_global_di_i8_exact() {1405; CHECK-LABEL: @const_gep_global_di_i8_exact(1406; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_di, i64 4)1407;1408  ret ptr getelementptr (i8, ptr @g_i32_di, i64 4)1409}1410 1411define ptr @const_gep_global_di_i8_larger() {1412; CHECK-LABEL: @const_gep_global_di_i8_larger(1413; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_di, i64 5)1414;1415  ret ptr getelementptr (i8, ptr @g_i32_di, i64 5)1416}1417 1418define ptr @const_gep_global_di_i64_larger() {1419; CHECK-LABEL: @const_gep_global_di_i64_larger(1420; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_di, i64 8)1421;1422  ret ptr getelementptr (i64, ptr @g_i32_di, i64 1)1423}1424 1425define ptr @const_gep_global_e_smaller() {1426; CHECK-LABEL: @const_gep_global_e_smaller(1427; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_e, i64 3)1428;1429  ret ptr getelementptr (i8, ptr @g_i32_e, i64 3)1430}1431 1432define ptr @const_gep_global_e_exact() {1433; CHECK-LABEL: @const_gep_global_e_exact(1434; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_e, i64 4)1435;1436  ret ptr getelementptr (i8, ptr @g_i32_e, i64 4)1437}1438 1439define ptr @const_gep_global_e_larger() {1440; CHECK-LABEL: @const_gep_global_e_larger(1441; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_e, i64 5)1442;1443  ret ptr getelementptr (i8, ptr @g_i32_e, i64 5)1444}1445 1446define ptr @const_gep_global_ew_smaller() {1447; CHECK-LABEL: @const_gep_global_ew_smaller(1448; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 3)1449;1450  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 3)1451}1452 1453define ptr @const_gep_global_ew_exact() {1454; CHECK-LABEL: @const_gep_global_ew_exact(1455; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 4)1456;1457  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 4)1458}1459 1460define ptr @const_gep_global_ew_larger() {1461; CHECK-LABEL: @const_gep_global_ew_larger(1462; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 5)1463;1464  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 5)1465}1466 1467define ptr @const_gep_0xi8_global() {1468; CHECK-LABEL: @const_gep_0xi8_global(1469; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_0xi8_e, i64 10)1470;1471  ret ptr getelementptr ([0 x i8], ptr @g_0xi8_e, i64 0, i64 10)1472}1473 1474define ptr @const_gep_chain(ptr %p, i64 %a) {1475; CHECK-LABEL: @const_gep_chain(1476; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[A:%.*]]1477; CHECK-NEXT:    [[P4:%.*]] = getelementptr inbounds nuw i8, ptr [[P1]], i64 61478; CHECK-NEXT:    ret ptr [[P4]]1479;1480  %p1 = getelementptr inbounds i8, ptr %p, i64 %a1481  %p2 = getelementptr inbounds i8, ptr %p1, i64 11482  %p3 = getelementptr inbounds i8, ptr %p2, i64 21483  %p4 = getelementptr inbounds i8, ptr %p3, i64 31484  ret ptr %p41485}1486 1487define ptr @gep_sdiv(ptr %p, i64 %off) {1488; CHECK-LABEL: @gep_sdiv(1489; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1490; CHECK-NEXT:    ret ptr [[PTR]]1491;1492  %index = sdiv exact i64 %off, 71493  %ptr = getelementptr %struct.C, ptr %p, i64 %index1494  ret ptr %ptr1495}1496 1497define ptr @gep_udiv(ptr %p, i64 %off) {1498; CHECK-LABEL: @gep_udiv(1499; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1500; CHECK-NEXT:    ret ptr [[PTR]]1501;1502  %index = udiv exact i64 %off, 71503  %ptr = getelementptr %struct.C, ptr %p, i64 %index1504  ret ptr %ptr1505}1506 1507define <2 x ptr> @gep_sdiv_vec(<2 x ptr> %p, <2 x i64> %off) {1508; CHECK-LABEL: @gep_sdiv_vec(1509; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, <2 x ptr> [[P:%.*]], <2 x i64> [[OFF:%.*]]1510; CHECK-NEXT:    ret <2 x ptr> [[PTR]]1511;1512  %index = sdiv exact <2 x i64> %off, <i64 7, i64 7>1513  %ptr = getelementptr %struct.C, <2 x ptr> %p, <2 x i64> %index1514  ret <2 x ptr> %ptr1515}1516 1517define ptr @gep_sdiv_inbounds(ptr %p, i64 %off) {1518; CHECK-LABEL: @gep_sdiv_inbounds(1519; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1520; CHECK-NEXT:    ret ptr [[PTR]]1521;1522  %index = sdiv exact i64 %off, 71523  %ptr = getelementptr inbounds %struct.C, ptr %p, i64 %index1524  ret ptr %ptr1525}1526 1527define ptr @gep_sdiv_nuw(ptr %p, i64 %off) {1528; CHECK-LABEL: @gep_sdiv_nuw(1529; CHECK-NEXT:    [[PTR:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1530; CHECK-NEXT:    ret ptr [[PTR]]1531;1532  %index = sdiv exact i64 %off, 71533  %ptr = getelementptr nuw %struct.C, ptr %p, i64 %index1534  ret ptr %ptr1535}1536 1537define ptr @gep_ashr(ptr %p, i64 %off) {1538; CHECK-LABEL: @gep_ashr(1539; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1540; CHECK-NEXT:    ret ptr [[PTR]]1541;1542  %index = ashr exact i64 %off, 21543  %ptr = getelementptr i32, ptr %p, i64 %index1544  ret ptr %ptr1545}1546 1547define ptr @gep_lshr(ptr %p, i64 %off) {1548; CHECK-LABEL: @gep_lshr(1549; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1550; CHECK-NEXT:    ret ptr [[PTR]]1551;1552  %index = lshr exact i64 %off, 21553  %ptr = getelementptr i32, ptr %p, i64 %index1554  ret ptr %ptr1555}1556 1557; Negative tests1558 1559define ptr @gep_i8(ptr %p, i64 %off) {1560; CHECK-LABEL: @gep_i8(1561; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]1562; CHECK-NEXT:    ret ptr [[PTR]]1563;1564  %ptr = getelementptr i8, ptr %p, i64 %off1565  ret ptr %ptr1566}1567 1568define ptr @gep_sdiv_mismatched_size(ptr %p, i64 %off) {1569; CHECK-LABEL: @gep_sdiv_mismatched_size(1570; CHECK-NEXT:    [[INDEX:%.*]] = sdiv exact i64 [[OFF:%.*]], 201571; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]1572; CHECK-NEXT:    ret ptr [[PTR]]1573;1574  %index = sdiv exact i64 %off, 201575  %ptr = getelementptr %struct.C, ptr %p, i64 %index1576  ret ptr %ptr1577}1578 1579define ptr @gep_udiv_mismatched_size(ptr %p, i64 %off) {1580; CHECK-LABEL: @gep_udiv_mismatched_size(1581; CHECK-NEXT:    [[INDEX:%.*]] = udiv exact i64 [[OFF:%.*]], 201582; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]1583; CHECK-NEXT:    ret ptr [[PTR]]1584;1585  %index = udiv exact i64 %off, 201586  %ptr = getelementptr %struct.C, ptr %p, i64 %index1587  ret ptr %ptr1588}1589 1590define ptr @gep_sdiv_without_exact(ptr %p, i64 %off) {1591; CHECK-LABEL: @gep_sdiv_without_exact(1592; CHECK-NEXT:    [[INDEX:%.*]] = sdiv i64 [[OFF:%.*]], 71593; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]1594; CHECK-NEXT:    ret ptr [[PTR]]1595;1596  %index = sdiv i64 %off, 71597  %ptr = getelementptr %struct.C, ptr %p, i64 %index1598  ret ptr %ptr1599}1600 1601define ptr @gep_udiv_without_exact(ptr %p, i64 %off) {1602; CHECK-LABEL: @gep_udiv_without_exact(1603; CHECK-NEXT:    [[INDEX:%.*]] = udiv i64 [[OFF:%.*]], 71604; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]1605; CHECK-NEXT:    ret ptr [[PTR]]1606;1607  %index = udiv i64 %off, 71608  %ptr = getelementptr %struct.C, ptr %p, i64 %index1609  ret ptr %ptr1610}1611 1612define ptr @gep_ashr_without_exact(ptr %p, i64 %off) {1613; CHECK-LABEL: @gep_ashr_without_exact(1614; CHECK-NEXT:    [[INDEX:%.*]] = ashr i64 [[OFF:%.*]], 21615; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]1616; CHECK-NEXT:    ret ptr [[PTR]]1617;1618  %index = ashr i64 %off, 21619  %ptr = getelementptr i32, ptr %p, i64 %index1620  ret ptr %ptr1621}1622 1623define ptr @gep_lshr_without_exact(ptr %p, i64 %off) {1624; CHECK-LABEL: @gep_lshr_without_exact(1625; CHECK-NEXT:    [[INDEX:%.*]] = lshr i64 [[OFF:%.*]], 21626; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]1627; CHECK-NEXT:    ret ptr [[PTR]]1628;1629  %index = lshr i64 %off, 21630  %ptr = getelementptr i32, ptr %p, i64 %index1631  ret ptr %ptr1632}1633 1634define i1 @test_only_used_by_icmp(ptr %a, ptr %b, ptr %c) {1635; CHECK-LABEL: @test_only_used_by_icmp(1636; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]1637; CHECK-NEXT:    ret i1 [[CMP]]1638;1639  %pa = ptrtoint ptr %a to i641640  %pb = ptrtoint ptr %b to i641641  %sub = sub i64 %pb, %pa1642  %gep = getelementptr i8, ptr %a, i64 %sub1643  %cmp = icmp eq ptr %gep, %c1644  ret i1 %cmp1645}1646 1647define i64 @test_only_used_by_ptrtoint(ptr %a, ptr %b) {1648; CHECK-LABEL: @test_only_used_by_ptrtoint(1649; CHECK-NEXT:    [[VAL:%.*]] = ptrtoint ptr [[B:%.*]] to i641650; CHECK-NEXT:    ret i64 [[VAL]]1651;1652  %pa = ptrtoint ptr %a to i641653  %pb = ptrtoint ptr %b to i641654  %sub = sub i64 %pb, %pa1655  %gep = getelementptr i8, ptr %a, i64 %sub1656  %val = ptrtoint ptr %gep to i641657  ret i64 %val1658}1659 1660define i64 @test_used_by_both(ptr %a, ptr %b, ptr %c) {1661; CHECK-LABEL: @test_used_by_both(1662; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]1663; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1664; CHECK:       if.then:1665; CHECK-NEXT:    [[VAL:%.*]] = ptrtoint ptr [[B]] to i641666; CHECK-NEXT:    ret i64 [[VAL]]1667; CHECK:       if.else:1668; CHECK-NEXT:    ret i64 01669;1670  %pa = ptrtoint ptr %a to i641671  %pb = ptrtoint ptr %b to i641672  %sub = sub i64 %pb, %pa1673  %gep = getelementptr i8, ptr %a, i64 %sub1674  %cmp = icmp eq ptr %gep, %c1675  br i1 %cmp, label %if.then, label %if.else1676if.then:1677  %val = ptrtoint ptr %gep to i641678  ret i64 %val1679if.else:1680  ret i64 01681}1682 1683; Negative tests1684 1685define i64 @test_used_by_both_invalid(ptr %a, ptr %b, ptr %c) {1686; CHECK-LABEL: @test_used_by_both_invalid(1687; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]1688; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1689; CHECK:       if.then:1690; CHECK-NEXT:    [[PB:%.*]] = ptrtoint ptr [[B]] to i641691; CHECK-NEXT:    [[PA:%.*]] = ptrtoint ptr [[A:%.*]] to i641692; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[PB]], [[PA]]1693; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[SUB]]1694; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[GEP]], align 81695; CHECK-NEXT:    ret i64 [[VAL]]1696; CHECK:       if.else:1697; CHECK-NEXT:    ret i64 01698;1699  %pa = ptrtoint ptr %a to i641700  %pb = ptrtoint ptr %b to i641701  %sub = sub i64 %pb, %pa1702  %gep = getelementptr i8, ptr %a, i64 %sub1703  %cmp = icmp eq ptr %gep, %c1704  br i1 %cmp, label %if.then, label %if.else1705if.then:1706  %val = load i64, ptr %gep, align 81707  ret i64 %val1708if.else:1709  ret i64 01710}1711 1712 1713@g = external global i81714 1715define ptr @constexpr_gep_of_gep_with_narrow_type() {1716; CHECK-LABEL: @constexpr_gep_of_gep_with_narrow_type(1717; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g, i64 254)1718;1719  ret ptr getelementptr (i8, ptr getelementptr (i8, ptr @g, i8 127), i8 127)1720}1721 1722define ptr @gep_to_i8_nusw_nuw(ptr %p) {1723; CHECK-LABEL: @gep_to_i8_nusw_nuw(1724; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 41725; CHECK-NEXT:    ret ptr [[GEP]]1726;1727  %gep = getelementptr nusw nuw i32, ptr %p, i64 11728  ret ptr %gep1729}1730 1731define ptr @gep_sel_const(i1 %c) {1732; CHECK-LABEL: @gep_sel_const(1733; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[C:%.*]], ptr getelementptr (i8, ptr @A, i64 5), ptr getelementptr (i8, ptr @B, i64 5)1734; CHECK-NEXT:    ret ptr [[GEP]]1735;1736  %sel = select i1 %c, ptr @A, ptr @B1737  %gep = getelementptr i8, ptr %sel, i64 51738  ret ptr %gep1739}1740 1741define ptr @gep_sel_const_nuw(i1 %c) {1742; CHECK-LABEL: @gep_sel_const_nuw(1743; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[C:%.*]], ptr getelementptr nuw (i8, ptr @A, i64 5), ptr getelementptr nuw (i8, ptr @B, i64 5)1744; CHECK-NEXT:    ret ptr [[GEP]]1745;1746  %sel = select i1 %c, ptr @A, ptr @B1747  %gep = getelementptr nuw i8, ptr %sel, i64 51748  ret ptr %gep1749}1750 1751define ptr @gep_of_udiv(ptr %p, i64 %x) {1752; CHECK-LABEL: @gep_of_udiv(1753; CHECK-NEXT:    [[TMP1:%.*]] = udiv exact i64 [[X:%.*]], 31754; CHECK-NEXT:    [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]1755; CHECK-NEXT:    ret ptr [[R]]1756;1757  %idx = udiv exact i64 %x, 121758  %r = getelementptr i32, ptr %p, i64 %idx1759  ret ptr %r1760}1761 1762define ptr @gep_of_udiv_fail_not_divisible(ptr %p, i64 %x) {1763; CHECK-LABEL: @gep_of_udiv_fail_not_divisible(1764; CHECK-NEXT:    [[IDX:%.*]] = udiv exact i64 [[X:%.*]], 131765; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]1766; CHECK-NEXT:    ret ptr [[R]]1767;1768  %idx = udiv exact i64 %x, 131769  %r = getelementptr i32, ptr %p, i64 %idx1770  ret ptr %r1771}1772 1773 1774define ptr @gep_of_sdiv(ptr %p, i64 %x) {1775; CHECK-LABEL: @gep_of_sdiv(1776; CHECK-NEXT:    [[TMP1:%.*]] = sdiv exact i64 [[X:%.*]], -91777; CHECK-NEXT:    [[R:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 [[TMP1]]1778; CHECK-NEXT:    ret ptr [[R]]1779;1780  %idx = sdiv exact i64 %x, -361781  %r = getelementptr nusw nuw i32, ptr %p, i64 %idx1782  ret ptr %r1783}1784 1785 1786define ptr @gep_of_sdiv_fail_not_divisible(ptr %p, i64 %x) {1787; CHECK-LABEL: @gep_of_sdiv_fail_not_divisible(1788; CHECK-NEXT:    [[IDX:%.*]] = sdiv exact i64 [[X:%.*]], -351789; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]1790; CHECK-NEXT:    ret ptr [[R]]1791;1792  %idx = sdiv exact i64 %x, -351793  %r = getelementptr i32, ptr %p, i64 %idx1794  ret ptr %r1795}1796 1797define ptr @gep_of_sdiv_fail_ub(ptr %p, i64 %x) {1798; CHECK-LABEL: @gep_of_sdiv_fail_ub(1799; CHECK-NEXT:    [[IDX:%.*]] = sdiv i64 [[X:%.*]], -41800; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]1801; CHECK-NEXT:    ret ptr [[R]]1802;1803  %idx = sdiv i64 %x, -41804  %r = getelementptr i32, ptr %p, i64 %idx1805  ret ptr %r1806}1807 1808define ptr @gep_of_lshr(ptr %p, i64 %x) {1809; CHECK-LABEL: @gep_of_lshr(1810; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i64 [[X:%.*]], 11811; CHECK-NEXT:    [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]1812; CHECK-NEXT:    ret ptr [[R]]1813;1814  %idx = lshr exact i64 %x, 31815  %r = getelementptr i32, ptr %p, i64 %idx1816  ret ptr %r1817}1818 1819define ptr @gep_of_ashr(ptr %p, i64 %x) {1820; CHECK-LABEL: @gep_of_ashr(1821; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i64 [[X:%.*]], 11822; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[TMP1]]1823; CHECK-NEXT:    ret ptr [[R]]1824;1825  %idx = ashr exact i64 %x, 31826  %r = getelementptr inbounds i32, ptr %p, i64 %idx1827  ret ptr %r1828}1829 1830define ptr @gep_of_ashr_fail_multiuse(ptr %p, i64 %x) {1831; CHECK-LABEL: @gep_of_ashr_fail_multiuse(1832; CHECK-NEXT:    [[IDX:%.*]] = ashr exact i64 [[X:%.*]], 31833; CHECK-NEXT:    call void @use.i64(i64 [[IDX]])1834; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[IDX]]1835; CHECK-NEXT:    ret ptr [[R]]1836;1837  %idx = ashr exact i64 %x, 31838  call void @use.i64(i64 %idx)1839  %r = getelementptr inbounds i32, ptr %p, i64 %idx1840  ret ptr %r1841}1842 1843define ptr @gep_of_lshr_fail_missing_exact(ptr %p, i64 %x) {1844; CHECK-LABEL: @gep_of_lshr_fail_missing_exact(1845; CHECK-NEXT:    [[IDX:%.*]] = lshr i64 [[X:%.*]], 31846; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]1847; CHECK-NEXT:    ret ptr [[R]]1848;1849  %idx = lshr i64 %x, 31850  %r = getelementptr i32, ptr %p, i64 %idx1851  ret ptr %r1852}1853 1854define ptr @gep_of_ashr_fail_not_divisible(ptr %p, i64 %x) {1855; CHECK-LABEL: @gep_of_ashr_fail_not_divisible(1856; CHECK-NEXT:    [[IDX:%.*]] = ashr exact i64 [[X:%.*]], 11857; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]1858; CHECK-NEXT:    ret ptr [[R]]1859;1860  %idx = ashr exact i64 %x, 11861  %r = getelementptr i32, ptr %p, i64 %idx1862  ret ptr %r1863}1864 1865define ptr @gep_merge_not_nuw(ptr %p, i64 %idx) {1866; CHECK-LABEL: @gep_merge_not_nuw(1867; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 -11868; CHECK-NEXT:    ret ptr [[GEP]]1869;1870  %idx.neg = sub i64 0, %idx1871  %add = add i64 %idx, -11872  %gep1 = getelementptr inbounds i8, ptr %p, i64 %idx.neg1873  %gep = getelementptr inbounds nuw i8, ptr %gep1, i64 %add1874  ret ptr %gep1875}1876 1877define ptr @gep_merge_nuw(ptr %p, i64 %x, i64 %y) {1878; CHECK-LABEL: @gep_merge_nuw(1879; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[Y:%.*]]1880; CHECK-NEXT:    ret ptr [[GEP]]1881;1882  %sub = sub i64 %y, %x1883  %gep1 = getelementptr nuw i8, ptr %p, i64 %x1884  %gep = getelementptr nuw i8, ptr %gep1, i64 %sub1885  ret ptr %gep1886}1887 1888define ptr @gep_merge_nuw_only_one1(ptr %p, i64 %x, i64 %y) {1889; CHECK-LABEL: @gep_merge_nuw_only_one1(1890; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]1891; CHECK-NEXT:    ret ptr [[GEP]]1892;1893  %sub = sub i64 %y, %x1894  %gep1 = getelementptr i8, ptr %p, i64 %x1895  %gep = getelementptr nuw i8, ptr %gep1, i64 %sub1896  ret ptr %gep1897}1898 1899define ptr @gep_merge_nuw_only_one2(ptr %p, i64 %x, i64 %y) {1900; CHECK-LABEL: @gep_merge_nuw_only_one2(1901; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]1902; CHECK-NEXT:    ret ptr [[GEP]]1903;1904  %sub = sub i64 %y, %x1905  %gep1 = getelementptr nuw i8, ptr %p, i64 %x1906  %gep = getelementptr i8, ptr %gep1, i64 %sub1907  ret ptr %gep1908}1909 1910; Cannot preserve nusw, unless we know that the addition x + (y-x)1911; does not overflow.1912define ptr @gep_merge_nusw(ptr %p, i64 %x, i64 %y) {1913; CHECK-LABEL: @gep_merge_nusw(1914; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]1915; CHECK-NEXT:    ret ptr [[GEP]]1916;1917  %sub = sub i64 %y, %x1918  %gep1 = getelementptr nusw i8, ptr %p, i64 %x1919  %gep = getelementptr nusw i8, ptr %gep1, i64 %sub1920  ret ptr %gep1921}1922 1923define ptr @gep_merge_nuw_add_zero(ptr %p, i64 %idx, i64 %idx2) {1924; CHECK-LABEL: @gep_merge_nuw_add_zero(1925; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw [2 x i32], ptr [[GEP_SPLIT:%.*]], i64 [[IDX2:%.*]]1926; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nuw i32, ptr [[GEP]], i64 [[IDX3:%.*]]1927; CHECK-NEXT:    ret ptr [[GEP1]]1928;1929  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx1930  %gep = getelementptr nuw [2 x i32], ptr %gep1, i64 0, i64 %idx21931  ret ptr %gep1932}1933 1934; Cannot preserve nusw, even if the merge only involves an add with a zero1935; index. This is because the whole offset calculation is required to be nsw1936; after the merge.1937define ptr @gep_merge_nusw_add_zero(ptr %p, i64 %idx, i64 %idx2) {1938; CHECK-LABEL: @gep_merge_nusw_add_zero(1939; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nusw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]1940; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]1941; CHECK-NEXT:    ret ptr [[GEP]]1942;1943  %gep1 = getelementptr nusw [2 x i32], ptr %p, i64 %idx1944  %gep = getelementptr nusw [2 x i32], ptr %gep1, i64 0, i64 %idx21945  ret ptr %gep1946}1947 1948define ptr @gep_merge_nuw_const(ptr %p, i64 %idx, i64 %idx2) {1949; CHECK-LABEL: @gep_merge_nuw_const(1950; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]1951; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[GEP1]], i64 41952; CHECK-NEXT:    ret ptr [[GEP]]1953;1954  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx1955  %gep = getelementptr nuw i8, ptr %gep1, i64 41956  ret ptr %gep1957}1958 1959define ptr @gep_merge_nuw_const_neg(ptr %p, i64 %idx, i64 %idx2) {1960; CHECK-LABEL: @gep_merge_nuw_const_neg(1961; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]1962; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[GEP1]], i64 -41963; CHECK-NEXT:    ret ptr [[GEP]]1964;1965  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx1966  %gep = getelementptr nuw i8, ptr %gep1, i64 -41967  ret ptr %gep1968}1969 1970; Cannot preserve nusw, because we don't know that the new offset calculation1971; does not overflow.1972define ptr @gep_merge_nusw_const(ptr %p, i64 %idx, i64 %idx2) {1973; CHECK-LABEL: @gep_merge_nusw_const(1974; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nusw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]1975; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[GEP1]], i64 41976; CHECK-NEXT:    ret ptr [[GEP]]1977;1978  %gep1 = getelementptr nusw [2 x i32], ptr %p, i64 %idx1979  %gep = getelementptr nusw i8, ptr %gep1, i64 41980  ret ptr %gep1981}1982 1983define ptr @gep_index_trunc_nothing(ptr %p, i128 %idx) {1984; CHECK-LABEL: @gep_index_trunc_nothing(1985; CHECK-NEXT:    [[TMP1:%.*]] = trunc i128 [[IDX:%.*]] to i641986; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]1987; CHECK-NEXT:    ret ptr [[GEP]]1988;1989  %gep = getelementptr i8, ptr %p, i128 %idx1990  ret ptr %gep1991}1992 1993define ptr @gep_index_trunc_nuw(ptr %p, i128 %idx) {1994; CHECK-LABEL: @gep_index_trunc_nuw(1995; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw i128 [[IDX:%.*]] to i641996; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[TMP1]]1997; CHECK-NEXT:    ret ptr [[GEP]]1998;1999  %gep = getelementptr nuw i8, ptr %p, i128 %idx2000  ret ptr %gep2001}2002 2003define ptr @gep_index_trunc_nusw(ptr %p, i128 %idx) {2004; CHECK-LABEL: @gep_index_trunc_nusw(2005; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i128 [[IDX:%.*]] to i642006; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[TMP1]]2007; CHECK-NEXT:    ret ptr [[GEP]]2008;2009  %gep = getelementptr nusw i8, ptr %p, i128 %idx2010  ret ptr %gep2011}2012 2013define ptr @gep_index_trunc_inbounds(ptr %p, i128 %idx) {2014; CHECK-LABEL: @gep_index_trunc_inbounds(2015; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i128 [[IDX:%.*]] to i642016; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[TMP1]]2017; CHECK-NEXT:    ret ptr [[GEP]]2018;2019  %gep = getelementptr inbounds i8, ptr %p, i128 %idx2020  ret ptr %gep2021}2022 2023define ptr @gep_index_trunc_nusw_nuw(ptr %p, i128 %idx) {2024; CHECK-LABEL: @gep_index_trunc_nusw_nuw(2025; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw nsw i128 [[IDX:%.*]] to i642026; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 [[TMP1]]2027; CHECK-NEXT:    ret ptr [[GEP]]2028;2029  %gep = getelementptr nusw nuw i8, ptr %p, i128 %idx2030  ret ptr %gep2031}2032 2033define ptr @gep_index_ext_nothing(ptr %p, i32 %idx) {2034; CHECK-LABEL: @gep_index_ext_nothing(2035; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i642036; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]2037; CHECK-NEXT:    ret ptr [[GEP]]2038;2039  %gep = getelementptr i8, ptr %p, i32 %idx2040  ret ptr %gep2041}2042 2043define ptr @gep_index_ext_nuw(ptr %p, i32 %idx) {2044; CHECK-LABEL: @gep_index_ext_nuw(2045; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i642046; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[TMP1]]2047; CHECK-NEXT:    ret ptr [[GEP]]2048;2049  %gep = getelementptr nuw i8, ptr %p, i32 %idx2050  ret ptr %gep2051}2052 2053define ptr @gep_index_ext_nusw(ptr %p, i32 %idx) {2054; CHECK-LABEL: @gep_index_ext_nusw(2055; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i642056; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[TMP1]]2057; CHECK-NEXT:    ret ptr [[GEP]]2058;2059  %gep = getelementptr nuw i8, ptr %p, i32 %idx2060  ret ptr %gep2061}2062 2063define ptr @gep_index_ext_nusw_nuw(ptr %p, i32 %idx) {2064; CHECK-LABEL: @gep_index_ext_nusw_nuw(2065; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[IDX:%.*]] to i642066; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 [[TMP1]]2067; CHECK-NEXT:    ret ptr [[GEP]]2068;2069  %gep = getelementptr nusw nuw i8, ptr %p, i32 %idx2070  ret ptr %gep2071}2072 2073!0 = !{!"branch_weights", i32 2, i32 10}2074