brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.8 KiB · bf97880 Raw
642 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes2; Check that we can fold operations with (gep null) inputs.3; Note: the LLParser already does some constant folding, check that output first:4; RUN: opt -passes=verify -S < %s | FileCheck %s --check-prefixes=ALL,LLPARSER5; We should be able to fold almost everything in InstSimplify other than the final test which requries InstCombine6; RUN: opt -S -passes=instsimplify < %s | FileCheck %s --check-prefixes=ALL,CHECK,INSTSIMPLIFY7; RUN: opt -S -passes=instcombine < %s | FileCheck %s --check-prefixes=ALL,CHECK,INSTCOMBINE8; Non-integral pointers limit certain transformations on pointers:9; RUN: sed -e 's/p:64:64:64:64/p:64:64:64:64-ni:1/g' %s | opt -S -passes=instsimplify | \10; RUN:   FileCheck %s --check-prefixes=ALL,CHECK,INSTSIMPLIFY11; RUN: sed -e 's/p:64:64:64:64/p:64:64:64:64-ni:1/g' %s | opt -S -passes=instcombine | \12; RUN:   FileCheck %s --check-prefixes=ALL,CHECK,INSTCOMBINE13target datalayout = "p:64:64:64:64"14 15declare void @use_i64(i64)16declare void @use_ptr(ptr addrspace(1))17 18define i64 @constant_fold_ptrtoint_gep_zero() {19; ALL-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_zero() {20; ALL-NEXT:    ret i64 021;22  ret i64 ptrtoint (ptr addrspace(1) null to i64)23}24define i64 @constant_fold_ptrtoint_gep_nonzero() {25; LLPARSER-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() {26; LLPARSER-NEXT:    ret i64 ptrtoint (ptr addrspace(1) getelementptr (i32, ptr addrspace(1) null, i64 1234) to i64)27;28; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() {29; INSTSIMPLIFY-NEXT:    ret i64 ptrtoint (ptr addrspace(1) getelementptr (i32, ptr addrspace(1) null, i64 1234) to i64)30;31; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() {32; INSTCOMBINE-NEXT:    ret i64 493633;34  ret i64 ptrtoint (ptr addrspace(1) getelementptr (i32, ptr addrspace(1) null, i64 1234) to i64)35}36 37define i64 @constant_fold_ptrtoint_gep_zero_inbounds() {38; ALL-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_zero_inbounds() {39; ALL-NEXT:    ret i64 040;41  ret i64 ptrtoint (ptr addrspace(1) null to i64)42}43 44; In theory we could fold this to poison/null, but that would break offsetof45; implementations that don't use __builtin_offsetof.46; TODO: should Clang special case ((INTEGER)&((TYPE *)0)->MEMBER) to emit a non-inbounds GEP?47define i64 @constant_fold_ptrtoint_gep_nonzero_inbounds() {48; LLPARSER-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() {49; LLPARSER-NEXT:    ret i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) null, i64 1234) to i64)50;51; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() {52; INSTSIMPLIFY-NEXT:    ret i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) null, i64 1234) to i64)53;54; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() {55; INSTCOMBINE-NEXT:    ret i64 493656;57  ret i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i32, ptr addrspace(1) null, i64 1234) to i64)58}59 60; Check all combinations of inbounds+non-inbounds GEP with the outer GEP having a non-zero offset61define void @constant_fold_ptrtoint_of_gep_of_nullgep() {62; LLPARSER-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() {63; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))64; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))65; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))66; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))67; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))68; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))69; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))70; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))71; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))72; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))73; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))74; LLPARSER-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))75; LLPARSER-NEXT:    ret void76;77; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() {78; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))79; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))80; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))81; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))82; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))83; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))84; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))85; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))86; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))87; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))88; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))89; INSTSIMPLIFY-NEXT:    call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))90; INSTSIMPLIFY-NEXT:    ret void91;92; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() {93; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)94; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)95; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)96; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)97; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)98; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)99; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)100; INSTCOMBINE-NEXT:    call void @use_i64(i64 1234)101; INSTCOMBINE-NEXT:    call void @use_i64(i64 0)102; INSTCOMBINE-NEXT:    call void @use_i64(i64 0)103; INSTCOMBINE-NEXT:    call void @use_i64(i64 0)104; INSTCOMBINE-NEXT:    call void @use_i64(i64 0)105; INSTCOMBINE-NEXT:    ret void106;107  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))108  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))109  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234) to i64))110  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234) to i64))111  ; Same again but this time with the inner GEP using the non-zero offset112  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234), i64 0) to i64))113  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 1234), i64 0) to i64))114  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234), i64 0) to i64))115  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 1234), i64 0) to i64))116  ; And finally with two constants that sum to zero117  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))118  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))119  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))120  call void @use_i64(i64 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr (i8, ptr addrspace(1) null, i64 -1), i64 1) to i64))121  ret void122}123 124; Another set of tests for instructions instead of constants125define i64 @fold_ptrtoint_nullgep_zero() {126; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_zero() {127; LLPARSER-NEXT:    [[OFFSET:%.*]] = add i64 0, 0128; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[OFFSET]]129; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64130; LLPARSER-NEXT:    ret i64 [[RET]]131;132; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_zero() {133; CHECK-NEXT:    ret i64 0134;135  %offset = add i64 0, 0136  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %offset137  %ret = ptrtoint ptr addrspace(1) %ptr to i64138  ret i64 %ret139}140 141define i64 @fold_ptrtoint_nullgep_zero_inbounds() {142; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_zero_inbounds() {143; LLPARSER-NEXT:    [[OFFSET:%.*]] = add i64 0, 0144; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[OFFSET]]145; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64146; LLPARSER-NEXT:    ret i64 [[RET]]147;148; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_zero_inbounds() {149; CHECK-NEXT:    ret i64 0150;151  %offset = add i64 0, 0152  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %offset153  %ret = ptrtoint ptr addrspace(1) %ptr to i64154  ret i64 %ret155}156 157define i64 @fold_ptrtoint_nullgep_nonzero() {158; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero() {159; LLPARSER-NEXT:    [[OFFSET:%.*]] = add i64 1234, 0160; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[OFFSET]]161; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64162; LLPARSER-NEXT:    ret i64 [[RET]]163;164; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero() {165; CHECK-NEXT:    ret i64 1234166;167  %offset = add i64 1234, 0168  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %offset169  %ret = ptrtoint ptr addrspace(1) %ptr to i64170  ret i64 %ret171}172 173; Inbounds constant null-GEP with non-zero could be constant-folded to null/poison,174; but folding it to the value makes ((INTEGER)&((TYPE *)0)->MEMBER) work.175define i64 @fold_ptrtoint_nullgep_nonzero_inbounds() {176; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero_inbounds() {177; LLPARSER-NEXT:    [[OFFSET:%.*]] = add i64 1234, 0178; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[OFFSET]]179; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64180; LLPARSER-NEXT:    ret i64 [[RET]]181;182; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero_inbounds() {183; CHECK-NEXT:    ret i64 1234184;185  %offset = add i64 1234, 0186  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %offset187  %ret = ptrtoint ptr addrspace(1) %ptr to i64188  ret i64 %ret189}190 191; We should be able to fold ptrtoint(gep null, x) to x192define i64 @fold_ptrtoint_nullgep_variable(i64 %val) {193; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable194; LLPARSER-SAME: (i64 [[VAL:%.*]]) {195; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[VAL]]196; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64197; LLPARSER-NEXT:    ret i64 [[RET]]198;199; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable200; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {201; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[VAL]]202; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64203; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]204;205; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable206; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {207; INSTCOMBINE-NEXT:    ret i64 [[VAL]]208;209  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %val210  %ret = ptrtoint ptr addrspace(1) %ptr to i64211  ret i64 %ret212}213 214; Inbounds null-GEP with non-zero offset could be folded to poison/null.215define i64 @fold_ptrtoint_nullgep_variable_known_nonzero(i64 %val) {216; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero217; LLPARSER-SAME: (i64 [[VAL:%.*]]) {218; LLPARSER-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1219; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]]220; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64221; LLPARSER-NEXT:    ret i64 [[RET]]222;223; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero224; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {225; INSTSIMPLIFY-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1226; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]]227; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64228; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]229;230; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero231; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {232; INSTCOMBINE-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1233; INSTCOMBINE-NEXT:    ret i64 [[NON_ZERO_OFFSET]]234;235  %non_zero_offset = or i64 %val, 1236  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %non_zero_offset237  %ret = ptrtoint ptr addrspace(1) %ptr to i64238  ret i64 %ret239}240 241; This is only valid if %val is zero so we could fold the result to 0.242define i64 @fold_ptrtoint_nullgep_variable_inbounds(i64 %val) {243; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_inbounds244; LLPARSER-SAME: (i64 [[VAL:%.*]]) {245; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[VAL]]246; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64247; LLPARSER-NEXT:    ret i64 [[RET]]248;249; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_inbounds250; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {251; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[VAL]]252; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64253; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]254;255; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_inbounds256; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {257; INSTCOMBINE-NEXT:    ret i64 [[VAL]]258;259  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %val260  %ret = ptrtoint ptr addrspace(1) %ptr to i64261  ret i64 %ret262}263 264; A non-constant but known-non-zero GEP could be folded to poison/null265define i64 @fold_ptrtoint_nullgep_variable_known_nonzero_inbounds(i64 %val) {266; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds267; LLPARSER-SAME: (i64 [[VAL:%.*]]) {268; LLPARSER-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1269; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]]270; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64271; LLPARSER-NEXT:    ret i64 [[RET]]272;273; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds274; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {275; INSTSIMPLIFY-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1276; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]]277; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64278; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]279;280; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds281; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {282; INSTCOMBINE-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1283; INSTCOMBINE-NEXT:    ret i64 [[NON_ZERO_OFFSET]]284;285  %non_zero_offset = or i64 %val, 1286  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %non_zero_offset287  %ret = ptrtoint ptr addrspace(1) %ptr to i64288  ret i64 %ret289}290 291; A non-constant but known-non-zero GEP could be folded to poison/null292define i64 @fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices(i64 %val) {293; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices294; LLPARSER-SAME: (i64 [[VAL:%.*]]) {295; LLPARSER-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1296; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds [2 x i8], ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]], i32 1297; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64298; LLPARSER-NEXT:    ret i64 [[RET]]299;300; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices301; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {302; INSTSIMPLIFY-NEXT:    [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1303; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr inbounds [2 x i8], ptr addrspace(1) null, i64 [[NON_ZERO_OFFSET]], i32 1304; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64305; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]306;307; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices308; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {309; INSTCOMBINE-NEXT:    [[NON_ZERO_OFFSET:%.*]] = shl i64 [[VAL]], 1310; INSTCOMBINE-NEXT:    [[RET:%.*]] = or i64 [[NON_ZERO_OFFSET]], 3311; INSTCOMBINE-NEXT:    ret i64 [[RET]]312;313  %non_zero_offset = or i64 %val, 1314  %ptr = getelementptr inbounds [2 x i8], ptr addrspace(1) null, i64 %non_zero_offset, i32 1315  %ret = ptrtoint ptr addrspace(1) %ptr to i64316  ret i64 %ret317}318 319; We can't fold non-i8 GEPs in InstSimplify since that would require adding new arithmetic.320; However, InstCombine can decompose the null gep and convert it to a shift.321define i64 @fold_ptrtoint_nullgep_i32_variable(i64 %val) {322; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_i32_variable323; LLPARSER-SAME: (i64 [[VAL:%.*]]) {324; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) null, i64 [[VAL]]325; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64326; LLPARSER-NEXT:    ret i64 [[RET]]327;328; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_i32_variable329; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {330; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) null, i64 [[VAL]]331; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64332; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]333;334; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_i32_variable335; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {336; INSTCOMBINE-NEXT:    [[PTR_IDX:%.*]] = shl i64 [[VAL]], 2337; INSTCOMBINE-NEXT:    ret i64 [[PTR_IDX]]338;339  %ptr = getelementptr i32, ptr addrspace(1) null, i64 %val340  %ret = ptrtoint ptr addrspace(1) %ptr to i64341  ret i64 %ret342}343 344; ptrtoint type does not match index type so requires requite a new trunc instruction345define i32 @fold_ptrtoint_nullgep_variable_trunc(i64 %val) {346; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc347; LLPARSER-SAME: (i64 [[VAL:%.*]]) {348; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[VAL]]349; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i32350; LLPARSER-NEXT:    ret i32 [[RET]]351;352; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc353; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) {354; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[VAL]]355; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i32356; INSTSIMPLIFY-NEXT:    ret i32 [[RET]]357;358; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc359; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) {360; INSTCOMBINE-NEXT:    [[RET:%.*]] = trunc i64 [[VAL]] to i32361; INSTCOMBINE-NEXT:    ret i32 [[RET]]362;363  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %val364  %ret = ptrtoint ptr addrspace(1) %ptr to i32365  ret i32 %ret366}367 368; For the following three tests, we could fold the result to poison/null since there is at least369; one inbounds GEP on null with a non-zero offset.370define i64 @fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() {371; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() {372; LLPARSER-NEXT:    [[NONZERO_OFFSET:%.*]] = add i64 1234, 0373; LLPARSER-NEXT:    [[ZERO_OFFSET:%.*]] = sub i64 [[NONZERO_OFFSET]], 1234374; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[NONZERO_OFFSET]]375; LLPARSER-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr addrspace(1) [[PTR]], i64 [[ZERO_OFFSET]]376; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR2]] to i64377; LLPARSER-NEXT:    ret i64 [[RET]]378;379; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() {380; CHECK-NEXT:    ret i64 1234381;382  %nonzero_offset = add i64 1234, 0383  %zero_offset = sub i64 %nonzero_offset, 1234384  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %nonzero_offset385  %ptr2 = getelementptr i8, ptr addrspace(1) %ptr, i64 %zero_offset386  %ret = ptrtoint ptr addrspace(1) %ptr2 to i64387  ret i64 %ret388}389 390define i64 @fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() {391; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() {392; LLPARSER-NEXT:    [[NONZERO_OFFSET:%.*]] = add i64 1234, 0393; LLPARSER-NEXT:    [[ZERO_OFFSET:%.*]] = sub i64 [[NONZERO_OFFSET]], 1234394; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr addrspace(1) null, i64 [[ZERO_OFFSET]]395; LLPARSER-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[PTR]], i64 [[NONZERO_OFFSET]]396; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR2]] to i64397; LLPARSER-NEXT:    ret i64 [[RET]]398;399; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() {400; CHECK-NEXT:    ret i64 1234401;402  %nonzero_offset = add i64 1234, 0403  %zero_offset = sub i64 %nonzero_offset, 1234404  %ptr = getelementptr i8, ptr addrspace(1) null, i64 %zero_offset405  %ptr2 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i64 %nonzero_offset406  %ret = ptrtoint ptr addrspace(1) %ptr2 to i64407  ret i64 %ret408}409 410; We should also be able to fold GEPs with multiple indices.411%struct.S = type { [2 x %struct.K] }412%struct.K = type { [32 x i8] }413 414define i64 @fold_complex_index_last_nonzero(i64 %x) local_unnamed_addr #0 {415; LLPARSER-LABEL: define {{[^@]+}}@fold_complex_index_last_nonzero416; LLPARSER-SAME: (i64 [[X:%.*]]) local_unnamed_addr {417; LLPARSER-NEXT:  entry:418; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr addrspace(1) null, i64 0, i32 0, i64 0, i32 0, i64 [[X]]419; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64420; LLPARSER-NEXT:    ret i64 [[RET]]421;422; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_complex_index_last_nonzero423; INSTSIMPLIFY-SAME: (i64 [[X:%.*]]) local_unnamed_addr {424; INSTSIMPLIFY-NEXT:  entry:425; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr addrspace(1) null, i64 0, i32 0, i64 0, i32 0, i64 [[X]]426; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64427; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]428;429; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_complex_index_last_nonzero430; INSTCOMBINE-SAME: (i64 [[X:%.*]]) local_unnamed_addr {431; INSTCOMBINE-NEXT:  entry:432; INSTCOMBINE-NEXT:    ret i64 [[X]]433;434entry:435  %ptr = getelementptr inbounds %struct.S, ptr addrspace(1) null, i64 0, i32 0, i64 0, i32 0, i64 %x436  %ret = ptrtoint ptr addrspace(1) %ptr to i64437  ret i64 %ret438}439 440define i64 @fold_complex_index_multiple_nonzero(i64 %x) local_unnamed_addr #0 {441; LLPARSER-LABEL: define {{[^@]+}}@fold_complex_index_multiple_nonzero442; LLPARSER-SAME: (i64 [[X:%.*]]) local_unnamed_addr {443; LLPARSER-NEXT:  entry:444; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr addrspace(1) null, i64 1, i32 0, i64 1, i32 0, i64 [[X]]445; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64446; LLPARSER-NEXT:    ret i64 [[RET]]447;448; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_complex_index_multiple_nonzero449; INSTSIMPLIFY-SAME: (i64 [[X:%.*]]) local_unnamed_addr {450; INSTSIMPLIFY-NEXT:  entry:451; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr addrspace(1) null, i64 1, i32 0, i64 1, i32 0, i64 [[X]]452; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64453; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]454;455; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_complex_index_multiple_nonzero456; INSTCOMBINE-SAME: (i64 [[X:%.*]]) local_unnamed_addr {457; INSTCOMBINE-NEXT:  entry:458; INSTCOMBINE-NEXT:    [[RET:%.*]] = add i64 [[X]], 96459; INSTCOMBINE-NEXT:    ret i64 [[RET]]460;461entry:462  %ptr = getelementptr inbounds %struct.S, ptr addrspace(1) null, i64 1, i32 0, i64 1, i32 0, i64 %x463  %ret = ptrtoint ptr addrspace(1) %ptr to i64464  ret i64 %ret465}466 467define i64 @fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() {468; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() {469; LLPARSER-NEXT:    [[NONZERO_OFFSET:%.*]] = add i64 1234, 0470; LLPARSER-NEXT:    [[ZERO_OFFSET:%.*]] = sub i64 [[NONZERO_OFFSET]], 1234471; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr addrspace(1) null, i64 [[NONZERO_OFFSET]]472; LLPARSER-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[PTR]], i64 [[ZERO_OFFSET]]473; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR2]] to i64474; LLPARSER-NEXT:    ret i64 [[RET]]475;476; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() {477; CHECK-NEXT:    ret i64 1234478;479  %nonzero_offset = add i64 1234, 0480  %zero_offset = sub i64 %nonzero_offset, 1234481  %ptr = getelementptr inbounds i8, ptr addrspace(1) null, i64 %nonzero_offset482  %ptr2 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i64 %zero_offset483  %ret = ptrtoint ptr addrspace(1) %ptr2 to i64484  ret i64 %ret485}486 487; Check that InstCombine can convert ptrtoint(gep null) with multiple indices488define i64 @fold_ptrtoint_nullgep_array_one_var_1(i64 %x) {489; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_1490; LLPARSER-SAME: (i64 [[X:%.*]]) {491; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 3492; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64493; LLPARSER-NEXT:    ret i64 [[RET]]494;495; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_1496; INSTSIMPLIFY-SAME: (i64 [[X:%.*]]) {497; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 3498; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64499; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]500;501; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_1502; INSTCOMBINE-SAME: (i64 [[X:%.*]]) {503; INSTCOMBINE-NEXT:    [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 2504; INSTCOMBINE-NEXT:    [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], 6505; INSTCOMBINE-NEXT:    ret i64 [[RET]]506;507  %ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 %x, i64 3508  %ret = ptrtoint ptr addrspace(1) %ptr to i64509  ret i64 %ret510}511 512define i64 @fold_ptrtoint_nullgep_array_one_var_2(i64 %x) {513; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_2514; LLPARSER-SAME: (i64 [[X:%.*]]) {515; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 7, i64 [[X]]516; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64517; LLPARSER-NEXT:    ret i64 [[RET]]518;519; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_2520; INSTSIMPLIFY-SAME: (i64 [[X:%.*]]) {521; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 7, i64 [[X]]522; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64523; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]524;525; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_array_one_var_2526; INSTCOMBINE-SAME: (i64 [[X:%.*]]) {527; INSTCOMBINE-NEXT:    [[PTR_IDX:%.*]] = shl i64 [[X]], 1528; INSTCOMBINE-NEXT:    [[RET:%.*]] = add i64 [[PTR_IDX]], 28529; INSTCOMBINE-NEXT:    ret i64 [[RET]]530;531  %ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 7, i64 %x532  %ret = ptrtoint ptr addrspace(1) %ptr to i64533  ret i64 %ret534}535 536define i64 @fold_ptrtoint_nested_array_two_vars(i64 %x, i64 %y) {537; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars538; LLPARSER-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {539; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]540; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64541; LLPARSER-NEXT:    ret i64 [[RET]]542;543; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars544; INSTSIMPLIFY-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {545; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]546; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64547; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]548;549; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars550; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {551; INSTCOMBINE-NEXT:    [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 2552; INSTCOMBINE-NEXT:    [[PTR_IDX:%.*]] = shl i64 [[Y]], 1553; INSTCOMBINE-NEXT:    [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_IDX]]554; INSTCOMBINE-NEXT:    ret i64 [[RET]]555;556 557  %ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 %x, i64 %y558  %ret = ptrtoint ptr addrspace(1) %ptr to i64559  ret i64 %ret560}561 562define i64 @fold_ptrtoint_nested_array_two_vars_plus_zero(i64 %x, i64 %y) {563; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_zero564; LLPARSER-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {565; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 [[X]], i64 [[Y]], i64 0566; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64567; LLPARSER-NEXT:    ret i64 [[RET]]568;569; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_zero570; INSTSIMPLIFY-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {571; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 [[X]], i64 [[Y]], i64 0572; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64573; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]574;575; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_zero576; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {577; INSTCOMBINE-NEXT:    [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 3578; INSTCOMBINE-NEXT:    [[PTR_IDX:%.*]] = shl i64 [[Y]], 2579; INSTCOMBINE-NEXT:    [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_IDX]]580; INSTCOMBINE-NEXT:    ret i64 [[RET]]581;582  %ptr = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 %x, i64 %y, i64 0583  %ret = ptrtoint ptr addrspace(1) %ptr to i64584  ret i64 %ret585}586 587define i64 @fold_ptrtoint_nested_array_two_vars_plus_const(i64 %x, i64 %y) {588; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_const589; LLPARSER-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {590; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 [[X]], i64 [[Y]], i64 1591; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64592; LLPARSER-NEXT:    ret i64 [[RET]]593;594; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_const595; INSTSIMPLIFY-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {596; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 [[X]], i64 [[Y]], i64 1597; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64598; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]599;600; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_const601; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {602; INSTCOMBINE-NEXT:    [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 3603; INSTCOMBINE-NEXT:    [[PTR_SPLIT1_IDX:%.*]] = shl i64 [[Y]], 2604; INSTCOMBINE-NEXT:    [[TMP1:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_SPLIT1_IDX]]605; INSTCOMBINE-NEXT:    [[RET:%.*]] = or disjoint i64 [[TMP1]], 2606; INSTCOMBINE-NEXT:    ret i64 [[RET]]607;608  %ptr = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 %x, i64 %y, i64 1609  %ret = ptrtoint ptr addrspace(1) %ptr to i64610  ret i64 %ret611}612 613; Negative test -- should not be folded since there are multiple GEP uses614define i64 @fold_ptrtoint_nested_nullgep_array_variable_multiple_uses(i64 %x, i64 %y) {615; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses616; LLPARSER-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {617; LLPARSER-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]618; LLPARSER-NEXT:    call void @use_ptr(ptr addrspace(1) [[PTR]])619; LLPARSER-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64620; LLPARSER-NEXT:    ret i64 [[RET]]621;622; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses623; INSTSIMPLIFY-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {624; INSTSIMPLIFY-NEXT:    [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]625; INSTSIMPLIFY-NEXT:    call void @use_ptr(ptr addrspace(1) [[PTR]])626; INSTSIMPLIFY-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64627; INSTSIMPLIFY-NEXT:    ret i64 [[RET]]628;629; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses630; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {631; INSTCOMBINE-NEXT:    [[PTR_SPLIT:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]]632; INSTCOMBINE-NEXT:    [[PTR:%.*]] = getelementptr i16, ptr addrspace(1) [[PTR_SPLIT]], i64 [[Y]]633; INSTCOMBINE-NEXT:    call void @use_ptr(ptr addrspace(1) [[PTR]])634; INSTCOMBINE-NEXT:    [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64635; INSTCOMBINE-NEXT:    ret i64 [[RET]]636;637  %ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 %x, i64 %y638  call void @use_ptr(ptr addrspace(1) %ptr)639  %ret = ptrtoint ptr addrspace(1) %ptr to i64640  ret i64 %ret641}642