Skip to content

Commit c3c5280

Browse files
committed
[InstSimplify] Delay creation of constants for offsets (NFC)
Return APInt from stripAndComputeConstantOffsets(), and only create corresponding Constants later, if we actually need them.
1 parent 83c2aa4 commit c3c5280

File tree

1 file changed

+25
-40
lines changed

1 file changed

+25
-40
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

+25-40
Original file line numberDiff line numberDiff line change
@@ -692,37 +692,29 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
692692
/// Compute the base pointer and cumulative constant offsets for V.
693693
///
694694
/// This strips all constant offsets off of V, leaving it the base pointer, and
695-
/// accumulates the total constant offset applied in the returned constant. It
696-
/// returns 0 if V is not a pointer, and returns the constant '0' if there are
697-
/// no constant offsets applied.
695+
/// accumulates the total constant offset applied in the returned constant.
696+
/// It returns zero if there are no constant offsets applied.
698697
///
699-
/// This is very similar to GetPointerBaseWithConstantOffset except it doesn't
700-
/// follow non-inbounds geps. This allows it to remain usable for icmp ult/etc.
701-
/// folding.
702-
static Constant *stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V,
703-
bool AllowNonInbounds = false) {
698+
/// This is very similar to stripAndAccumulateConstantOffsets(), except it
699+
/// normalizes the offset bitwidth to the stripped pointer type, not the
700+
/// original pointer type.
701+
static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V,
702+
bool AllowNonInbounds = false) {
704703
assert(V->getType()->isPtrOrPtrVectorTy());
705704

706705
APInt Offset = APInt::getZero(DL.getIndexTypeSizeInBits(V->getType()));
707-
708706
V = V->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds);
709707
// As that strip may trace through `addrspacecast`, need to sext or trunc
710708
// the offset calculated.
711-
Type *IntIdxTy = DL.getIndexType(V->getType())->getScalarType();
712-
Offset = Offset.sextOrTrunc(IntIdxTy->getIntegerBitWidth());
713-
714-
Constant *OffsetIntPtr = ConstantInt::get(IntIdxTy, Offset);
715-
if (VectorType *VecTy = dyn_cast<VectorType>(V->getType()))
716-
return ConstantVector::getSplat(VecTy->getElementCount(), OffsetIntPtr);
717-
return OffsetIntPtr;
709+
return Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(V->getType()));
718710
}
719711

720712
/// Compute the constant difference between two pointer values.
721713
/// If the difference is not a constant, returns zero.
722714
static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
723715
Value *RHS) {
724-
Constant *LHSOffset = stripAndComputeConstantOffsets(DL, LHS);
725-
Constant *RHSOffset = stripAndComputeConstantOffsets(DL, RHS);
716+
APInt LHSOffset = stripAndComputeConstantOffsets(DL, LHS);
717+
APInt RHSOffset = stripAndComputeConstantOffsets(DL, RHS);
726718

727719
// If LHS and RHS are not related via constant offsets to the same base
728720
// value, there is nothing we can do here.
@@ -733,7 +725,10 @@ static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
733725
// LHS - RHS
734726
// = (LHSOffset + Base) - (RHSOffset + Base)
735727
// = LHSOffset - RHSOffset
736-
return ConstantExpr::getSub(LHSOffset, RHSOffset);
728+
Constant *Res = ConstantInt::get(LHS->getContext(), LHSOffset - RHSOffset);
729+
if (auto *VecTy = dyn_cast<VectorType>(LHS->getType()))
730+
Res = ConstantVector::getSplat(VecTy->getElementCount(), Res);
731+
return Res;
737732
}
738733

739734
/// Given operands for a Sub, see if we can fold the result.
@@ -2592,15 +2587,14 @@ computePointerICmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
25922587
// Even if an non-inbounds GEP occurs along the path we can still optimize
25932588
// equality comparisons concerning the result.
25942589
bool AllowNonInbounds = ICmpInst::isEquality(Pred);
2595-
Constant *LHSOffset =
2596-
stripAndComputeConstantOffsets(DL, LHS, AllowNonInbounds);
2597-
Constant *RHSOffset =
2598-
stripAndComputeConstantOffsets(DL, RHS, AllowNonInbounds);
2590+
APInt LHSOffset = stripAndComputeConstantOffsets(DL, LHS, AllowNonInbounds);
2591+
APInt RHSOffset = stripAndComputeConstantOffsets(DL, RHS, AllowNonInbounds);
25992592

26002593
// If LHS and RHS are related via constant offsets to the same base
26012594
// value, we can replace it with an icmp which just compares the offsets.
26022595
if (LHS == RHS)
2603-
return ConstantExpr::getICmp(Pred, LHSOffset, RHSOffset);
2596+
return ConstantInt::get(
2597+
GetCompareTy(LHS), ICmpInst::compare(LHSOffset, RHSOffset, Pred));
26042598

26052599
// Various optimizations for (in)equality comparisons.
26062600
if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) {
@@ -2635,32 +2629,23 @@ computePointerICmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
26352629
// address, due to canonicalization and constant folding.
26362630
if (isa<AllocaInst>(LHS) &&
26372631
(isa<AllocaInst>(RHS) || isa<GlobalVariable>(RHS))) {
2638-
ConstantInt *LHSOffsetCI = dyn_cast<ConstantInt>(LHSOffset);
2639-
ConstantInt *RHSOffsetCI = dyn_cast<ConstantInt>(RHSOffset);
26402632
uint64_t LHSSize, RHSSize;
26412633
ObjectSizeOpts Opts;
26422634
Opts.NullIsUnknownSize =
26432635
NullPointerIsDefined(cast<AllocaInst>(LHS)->getFunction());
2644-
if (LHSOffsetCI && RHSOffsetCI &&
2645-
getObjectSize(LHS, LHSSize, DL, TLI, Opts) &&
2646-
getObjectSize(RHS, RHSSize, DL, TLI, Opts)) {
2647-
const APInt &LHSOffsetValue = LHSOffsetCI->getValue();
2648-
const APInt &RHSOffsetValue = RHSOffsetCI->getValue();
2649-
if (!LHSOffsetValue.isNegative() &&
2650-
!RHSOffsetValue.isNegative() &&
2651-
LHSOffsetValue.ult(LHSSize) &&
2652-
RHSOffsetValue.ult(RHSSize)) {
2653-
return ConstantInt::get(GetCompareTy(LHS),
2654-
!CmpInst::isTrueWhenEqual(Pred));
2655-
}
2636+
if (getObjectSize(LHS, LHSSize, DL, TLI, Opts) &&
2637+
getObjectSize(RHS, RHSSize, DL, TLI, Opts) &&
2638+
!LHSOffset.isNegative() && !RHSOffset.isNegative() &&
2639+
LHSOffset.ult(LHSSize) && RHSOffset.ult(RHSSize)) {
2640+
return ConstantInt::get(GetCompareTy(LHS),
2641+
!CmpInst::isTrueWhenEqual(Pred));
26562642
}
26572643

26582644
// Repeat the above check but this time without depending on DataLayout
26592645
// or being able to compute a precise size.
26602646
if (!cast<PointerType>(LHS->getType())->isEmptyTy() &&
26612647
!cast<PointerType>(RHS->getType())->isEmptyTy() &&
2662-
LHSOffset->isNullValue() &&
2663-
RHSOffset->isNullValue())
2648+
LHSOffset.isNullValue() && RHSOffset.isNullValue())
26642649
return ConstantInt::get(GetCompareTy(LHS),
26652650
!CmpInst::isTrueWhenEqual(Pred));
26662651
}

0 commit comments

Comments
 (0)