diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1345,21 +1345,44 @@ default: llvm_unreachable("Missing case"); case Instruction::PtrToInt: - // If the input is a inttoptr, eliminate the pair. This requires knowing - // the width of a pointer, so it can't be done in ConstantExpr::getCast. if (auto *CE = dyn_cast(C)) { + Constant *FoldedValue = nullptr; + // If the input is a inttoptr, eliminate the pair. This requires knowing + // the width of a pointer, so it can't be done in ConstantExpr::getCast. if (CE->getOpcode() == Instruction::IntToPtr) { - Constant *Input = CE->getOperand(0); - unsigned InWidth = Input->getType()->getScalarSizeInBits(); - unsigned PtrWidth = DL.getPointerTypeSizeInBits(CE->getType()); - if (PtrWidth < InWidth) { - Constant *Mask = - ConstantInt::get(CE->getContext(), - APInt::getLowBitsSet(InWidth, PtrWidth)); - Input = ConstantExpr::getAnd(Input, Mask); + // zext/trunc the inttoptr to pointer size. + FoldedValue = ConstantExpr::getIntegerCast( + CE->getOperand(0), DL.getIntPtrType(CE->getType()), false); + } else if (auto *GEP = dyn_cast(CE)) { + // If we have GEP, we can perform the following folds: + // (ptrtoint (gep null, x)) -> x + // (ptrtoint (gep (gep null, x), y) -> x + y, etc. + // FIXME: is this also valid for non-integral pointers? I would assume + // so since this is a constant expression so it should evaluate to the + // same integer value? + unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); + APInt BaseOffset(BitWidth, 0); + auto *Base = cast( + GEP->stripAndAccumulateConstantOffsets(DL, BaseOffset, true)); + if (Base->isNullValue()) { + // FIXME: we could fold all ptrtoint(inbounds GEP) to zero here since + // that is the only valid offset for an inbounds GEP. If the offset is + // not zero, that GEP is poison so returning 0 is also valid + // (https://alive2.llvm.org/ce/z/Gzb5iH). However, Clang currently + // generates inbounds GEPs on NULL for hand-written offsetof + // expressions, so this risks miscompilation. + // TODO: Should there be a cl::opt<> to opt-in to this behaviour? + constexpr bool CanFoldNonzeroInboundsNullGEPToZero = false; + if (CanFoldNonzeroInboundsNullGEPToZero && GEP->isInBounds()) { + // Any non-zero inbounds GEP on NULL is poison, so we can return 0. + return ConstantInt::get(DestTy, 0); + } + FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset); } - // Do a zext or trunc to get to the dest size. - return ConstantExpr::getIntegerCast(Input, DestTy, false); + } + if (FoldedValue) { + // Do a zext or trunc to get to the ptrtoint dest size. + return ConstantExpr::getIntegerCast(FoldedValue, DestTy, false); } } return ConstantExpr::getCast(Opcode, C, DestTy); diff --git a/llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll b/llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll --- a/llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll +++ b/llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll @@ -3,13 +3,13 @@ ; Note: the LLParser already does some constant folding, check that output first: ; RUN: opt -S -passes=verify < %s | FileCheck %s --check-prefixes=ALL,LLPARSER ; We should be able to fold almost everything in InstSimplify other than the final test which requries InstCombine -; RUN: opt -S -passes=instsimplify < %s | FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,INTEGRAL,INTEGRAL-INSTSIMPLIFY -; RUN: opt -S -passes=instcombine < %s | FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,INTEGRAL,INTEGRAL-INSTCOMBINE +; RUN: opt -S -passes=instsimplify < %s | FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,INTEGRAL,INSTSIMPLIFY,INTEGRAL-INSTSIMPLIFY +; RUN: opt -S -passes=instcombine < %s | FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,INTEGRAL,INSTCOMBINE,INTEGRAL-INSTCOMBINE ; Non-integral pointers limit certain transformations on pointers: ; RUN: sed -e 's/p:64:64:64:64/p:64:64:64:64-ni:1/g' %s | opt -S -passes=instsimplify | \ -; RUN: FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,NONINTEGRAL,NONINTEGRAL-INSTSIMPLIFY +; RUN: FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,NONINTEGRAL,INSTSIMPLIFY,NONINTEGRAL-INSTSIMPLIFY ; RUN: sed -e 's/p:64:64:64:64/p:64:64:64:64-ni:1/g' %s | opt -S -passes=instcombine | \ -; RUN: FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,NONINTEGRAL,NONINTEGRAL-INSTCOMBINE +; RUN: FileCheck %s --allow-unused-prefixes --check-prefixes=ALL,CHECK,NONINTEGRAL,INSTCOMBINE,NONINTEGRAL-INSTCOMBINE target datalayout = "p:64:64:64:64" declare void @use_i64(i64) @@ -25,14 +25,11 @@ ; LLPARSER-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { ; LLPARSER-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* null, i64 1234) to i64) ; -; INTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { -; INTEGRAL-INSTSIMPLIFY-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* null, i64 1234) to i64) +; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { +; INSTSIMPLIFY-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* null, i64 1234) to i64) ; -; INTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { -; INTEGRAL-INSTCOMBINE-NEXT: ret i64 4936 -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* null, i64 1234) to i64) +; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero() { +; INSTCOMBINE-NEXT: ret i64 4936 ; ret i64 ptrtoint (i32 addrspace(1)* getelementptr (i32, i32 addrspace(1)* null, i64 1234) to i64) } @@ -53,14 +50,11 @@ ; LLPARSER-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { ; LLPARSER-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* null, i64 1234) to i64) ; -; INTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { -; INTEGRAL-INSTSIMPLIFY-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* null, i64 1234) to i64) -; -; INTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { -; INTEGRAL-INSTCOMBINE-NEXT: ret i64 4936 +; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { +; INSTSIMPLIFY-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* null, i64 1234) to i64) ; -; NONINTEGRAL-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* null, i64 1234) to i64) +; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_gep_nonzero_inbounds() { +; INSTCOMBINE-NEXT: ret i64 4936 ; ret i64 ptrtoint (i32 addrspace(1)* getelementptr inbounds (i32, i32 addrspace(1)* null, i64 1234) to i64) } @@ -82,50 +76,35 @@ ; LLPARSER-NEXT: call void @use_i64(i64 0) ; LLPARSER-NEXT: ret void ; -; INTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() { -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTSIMPLIFY-NEXT: ret void -; -; INTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() { -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 1234) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTCOMBINE-NEXT: call void @use_i64(i64 0) -; INTEGRAL-INSTCOMBINE-NEXT: ret void -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() { -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) -; NONINTEGRAL-NEXT: call void @use_i64(i64 0) -; NONINTEGRAL-NEXT: call void @use_i64(i64 0) -; NONINTEGRAL-NEXT: call void @use_i64(i64 0) -; NONINTEGRAL-NEXT: call void @use_i64(i64 0) -; NONINTEGRAL-NEXT: ret void +; INSTSIMPLIFY-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() { +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64)) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) +; INSTSIMPLIFY-NEXT: call void @use_i64(i64 0) +; INSTSIMPLIFY-NEXT: ret void +; +; INSTCOMBINE-LABEL: define {{[^@]+}}@constant_fold_ptrtoint_of_gep_of_nullgep() { +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 1234) +; INSTCOMBINE-NEXT: call void @use_i64(i64 0) +; INSTCOMBINE-NEXT: call void @use_i64(i64 0) +; INSTCOMBINE-NEXT: call void @use_i64(i64 0) +; INSTCOMBINE-NEXT: call void @use_i64(i64 0) +; INSTCOMBINE-NEXT: ret void ; call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 0), i64 1234) to i64)) call void @use_i64(i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 0), i64 1234) to i64)) @@ -184,11 +163,8 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero() { -; INTEGRAL-NEXT: ret i64 1234 -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64) +; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero() { +; CHECK-NEXT: ret i64 1234 ; %offset = add i64 1234, 0 %ptr = getelementptr i8, i8 addrspace(1)* null, i64 %offset @@ -204,11 +180,8 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero_inbounds() { -; INTEGRAL-NEXT: ret i64 1234 -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero_inbounds() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64) +; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_nonzero_inbounds() { +; CHECK-NEXT: ret i64 1234 ; %offset = add i64 1234, 0 %ptr = getelementptr inbounds i8, i8 addrspace(1)* null, i64 %offset @@ -281,33 +254,19 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices -; INTEGRAL-INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { -; INTEGRAL-INSTSIMPLIFY-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 -; INTEGRAL-INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i32 1 -; INTEGRAL-INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; INTEGRAL-INSTSIMPLIFY-NEXT: ret i64 [[RET]] -; -; INTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices -; INTEGRAL-INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { -; INTEGRAL-INSTCOMBINE-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 -; INTEGRAL-INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i64 1 -; INTEGRAL-INSTCOMBINE-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; INTEGRAL-INSTCOMBINE-NEXT: ret i64 [[RET]] -; -; NONINTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices -; NONINTEGRAL-INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { -; NONINTEGRAL-INSTSIMPLIFY-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 -; NONINTEGRAL-INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i32 1 -; NONINTEGRAL-INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; NONINTEGRAL-INSTSIMPLIFY-NEXT: ret i64 [[RET]] -; -; NONINTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices -; NONINTEGRAL-INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { -; NONINTEGRAL-INSTCOMBINE-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 -; NONINTEGRAL-INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i64 1 -; NONINTEGRAL-INSTCOMBINE-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; NONINTEGRAL-INSTCOMBINE-NEXT: ret i64 [[RET]] +; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices +; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { +; INSTSIMPLIFY-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 +; INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i32 1 +; INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 +; INSTSIMPLIFY-NEXT: ret i64 [[RET]] +; +; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_known_nonzero_inbounds_multiple_indices +; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { +; INSTCOMBINE-NEXT: [[NON_ZERO_OFFSET:%.*]] = or i64 [[VAL]], 1 +; INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 [[NON_ZERO_OFFSET]], i64 1 +; INSTCOMBINE-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 +; INSTCOMBINE-NEXT: ret i64 [[RET]] ; %non_zero_offset = or i64 %val, 1 %ptr = getelementptr inbounds [2 x i8], [2 x i8] addrspace(1)* null, i64 %non_zero_offset, i32 1 @@ -338,31 +297,18 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i32 ; LLPARSER-NEXT: ret i32 [[RET]] ; -; INTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc -; INTEGRAL-INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { -; INTEGRAL-INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] -; INTEGRAL-INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i32 -; INTEGRAL-INSTSIMPLIFY-NEXT: ret i32 [[RET]] -; -; INTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc -; INTEGRAL-INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { -; INTEGRAL-INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] -; INTEGRAL-INSTCOMBINE-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; INTEGRAL-INSTCOMBINE-NEXT: [[RET:%.*]] = trunc i64 [[TMP1]] to i32 -; INTEGRAL-INSTCOMBINE-NEXT: ret i32 [[RET]] -; -; NONINTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc -; NONINTEGRAL-INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { -; NONINTEGRAL-INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] -; NONINTEGRAL-INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i32 -; NONINTEGRAL-INSTSIMPLIFY-NEXT: ret i32 [[RET]] -; -; NONINTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc -; NONINTEGRAL-INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { -; NONINTEGRAL-INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] -; NONINTEGRAL-INSTCOMBINE-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 -; NONINTEGRAL-INSTCOMBINE-NEXT: [[RET:%.*]] = trunc i64 [[TMP1]] to i32 -; NONINTEGRAL-INSTCOMBINE-NEXT: ret i32 [[RET]] +; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc +; INSTSIMPLIFY-SAME: (i64 [[VAL:%.*]]) { +; INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] +; INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i32 +; INSTSIMPLIFY-NEXT: ret i32 [[RET]] +; +; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nullgep_variable_trunc +; INSTCOMBINE-SAME: (i64 [[VAL:%.*]]) { +; INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr i8, i8 addrspace(1)* null, i64 [[VAL]] +; INSTCOMBINE-NEXT: [[TMP1:%.*]] = ptrtoint i8 addrspace(1)* [[PTR]] to i64 +; INSTCOMBINE-NEXT: [[RET:%.*]] = trunc i64 [[TMP1]] to i32 +; INSTCOMBINE-NEXT: ret i32 [[RET]] ; %ptr = getelementptr i8, i8 addrspace(1)* null, i64 %val %ret = ptrtoint i8 addrspace(1)* %ptr to i32 @@ -382,14 +328,8 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR2]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() { -; INTEGRAL-NEXT: ret i64 1234 -; -; NONINTEGRAL-INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() { -; NONINTEGRAL-INSTSIMPLIFY-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64) -; -; NONINTEGRAL-INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() { -; NONINTEGRAL-INSTCOMBINE-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* null, i64 1234) to i64) +; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_zero_nullgep_of_nonzero_inbounds_nullgep() { +; CHECK-NEXT: ret i64 1234 ; %nonzero_offset = add i64 1234, 0 %zero_offset = sub i64 %nonzero_offset, 1234 @@ -408,11 +348,8 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR2]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() { -; INTEGRAL-NEXT: ret i64 1234 -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64) +; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_nonzero_inbounds_nullgep_of_zero_noninbounds_nullgep() { +; CHECK-NEXT: ret i64 1234 ; %nonzero_offset = add i64 1234, 0 %zero_offset = sub i64 %nonzero_offset, 1234 @@ -431,11 +368,8 @@ ; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint i8 addrspace(1)* [[PTR2]] to i64 ; LLPARSER-NEXT: ret i64 [[RET]] ; -; INTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() { -; INTEGRAL-NEXT: ret i64 1234 -; -; NONINTEGRAL-LABEL: define {{[^@]+}}@fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() { -; NONINTEGRAL-NEXT: ret i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 1234) to i64) +; CHECK-LABEL: define {{[^@]+}}@fold_ptrtoint_inbounds_nullgep_of_nonzero_inbounds_nullgep() { +; CHECK-NEXT: ret i64 1234 ; %nonzero_offset = add i64 1234, 0 %zero_offset = sub i64 %nonzero_offset, 1234