diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h --- a/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -248,7 +248,7 @@ const SimplifyQuery &Q); /// Given operands for a GetElementPtrInst, fold the result or return null. -Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, +Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, bool InBounds, const SimplifyQuery &Q); /// Given operands for an InsertValueInst, fold the result or return null. diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -70,8 +70,8 @@ static Value *SimplifyXorInst(Value *, Value *, const SimplifyQuery &, unsigned); static Value *SimplifyCastInst(unsigned, Value *, Type *, const SimplifyQuery &, unsigned); -static Value *SimplifyGEPInst(Type *, ArrayRef, const SimplifyQuery &, - unsigned); +static Value *SimplifyGEPInst(Type *, ArrayRef, bool, + const SimplifyQuery &, unsigned); static Value *SimplifySelectInst(Value *, Value *, Value *, const SimplifyQuery &, unsigned); @@ -3983,7 +3983,8 @@ if (auto *GEP = dyn_cast(I)) return PreventSelfSimplify(SimplifyGEPInst(GEP->getSourceElementType(), - NewOps, Q, MaxRecurse - 1)); + NewOps, GEP->isInBounds(), Q, + MaxRecurse - 1)); if (isa(I)) return PreventSelfSimplify( @@ -4328,7 +4329,7 @@ /// Given operands for an GetElementPtrInst, see if we can fold the result. /// If not, this returns null. -static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, +static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, bool InBounds, const SimplifyQuery &Q, unsigned) { // The type of the GEP pointer operand. unsigned AS = @@ -4448,13 +4449,13 @@ return nullptr; auto *CE = ConstantExpr::getGetElementPtr(SrcTy, cast(Ops[0]), - Ops.slice(1)); + Ops.slice(1), InBounds); return ConstantFoldConstant(CE, Q.DL); } -Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, +Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, bool InBounds, const SimplifyQuery &Q) { - return ::SimplifyGEPInst(SrcTy, Ops, Q, RecursionLimit); + return ::SimplifyGEPInst(SrcTy, Ops, InBounds, Q, RecursionLimit); } /// Given operands for an InsertValueInst, see if we can fold the result. @@ -6220,8 +6221,9 @@ Result = SimplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q); break; case Instruction::GetElementPtr: { - Result = SimplifyGEPInst(cast(I)->getSourceElementType(), - NewOps, Q); + auto *GEPI = cast(I); + Result = SimplifyGEPInst(GEPI->getSourceElementType(), NewOps, + GEPI->isInBounds(), Q); break; } case Instruction::InsertValue: { diff --git a/llvm/lib/Analysis/PHITransAddr.cpp b/llvm/lib/Analysis/PHITransAddr.cpp --- a/llvm/lib/Analysis/PHITransAddr.cpp +++ b/llvm/lib/Analysis/PHITransAddr.cpp @@ -226,8 +226,8 @@ return GEP; // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(GEP->getSourceElementType(), - GEPOps, {DL, TLI, DT, AC})) { + if (Value *V = SimplifyGEPInst(GEP->getSourceElementType(), GEPOps, + GEP->isInBounds(), {DL, TLI, DT, AC})) { for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) RemoveInstInputs(GEPOps[i], InstInputs); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1855,7 +1855,8 @@ Type *GEPType = GEP.getType(); Type *GEPEltType = GEP.getSourceElementType(); bool IsGEPSrcEleScalable = isa(GEPEltType); - if (Value *V = SimplifyGEPInst(GEPEltType, Ops, SQ.getWithInstruction(&GEP))) + if (Value *V = SimplifyGEPInst(GEPEltType, Ops, GEP.isInBounds(), + SQ.getWithInstruction(&GEP))) return replaceInstUsesWith(GEP, V); // For vector geps, use the generic demanded vector support. diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -1194,9 +1194,10 @@ SimplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), SQ); if (auto Simplified = checkExprResults(E, I, V)) return Simplified; - } else if (isa(I)) { - Value *V = SimplifyGEPInst( - E->getType(), ArrayRef(E->op_begin(), E->op_end()), SQ); + } else if (auto *GEPI = dyn_cast(I)) { + Value *V = SimplifyGEPInst(GEPI->getSourceElementType(), + ArrayRef(E->op_begin(), E->op_end()), + GEPI->isInBounds(), SQ); if (auto Simplified = checkExprResults(E, I, V)) return Simplified; } else if (AllConstant) { diff --git a/llvm/test/Transforms/InstSimplify/simplify-nested-bitcast.ll b/llvm/test/Transforms/InstSimplify/simplify-nested-bitcast.ll --- a/llvm/test/Transforms/InstSimplify/simplify-nested-bitcast.ll +++ b/llvm/test/Transforms/InstSimplify/simplify-nested-bitcast.ll @@ -28,7 +28,7 @@ } ; CHECK-LABEL: define void @f1 -; CHECK: %1 = load i32 (i8 addrspace(4)*, i32 addrspace(1)*)*, i32 (i8 addrspace(4)*, i32 addrspace(1)*)* addrspace(4)* bitcast (i8* addrspace(4)* getelementptr (%__aaa_struct, %__aaa_struct addrspace(4)* addrspacecast (%__aaa_struct addrspace(1)* @__aaa_struct_ptr to %__aaa_struct addrspace(4)*), i64 0, i32 0, i32 3) to i32 (i8 addrspace(4)*, i32 addrspace(1)*)* addrspace(4)*), align 8 +; CHECK: %1 = load i32 (i8 addrspace(4)*, i32 addrspace(1)*)*, i32 (i8 addrspace(4)*, i32 addrspace(1)*)* addrspace(4)* bitcast (i8* addrspace(4)* getelementptr inbounds (%__aaa_struct, %__aaa_struct addrspace(4)* addrspacecast (%__aaa_struct addrspace(1)* @__aaa_struct_ptr to %__aaa_struct addrspace(4)*), i64 0, i32 0, i32 3) to i32 (i8 addrspace(4)*, i32 addrspace(1)*)* addrspace(4)*), align 8 ; Function Attrs: alwaysinline nounwind define void @f1(i32 addrspace(1)*) #1 {