Skip to content

Commit a608607

Browse files
authored
[ConstraintElim] Add support for decomposing gep nuw (#118639)
ConstraintElimination currently only supports decomposing gep nusw with non-negative indices (with "non-negative" possibly being enforced via pre-condition). Add support for gep nuw, which directly gives us the necessary guarantees for the decomposition.
1 parent 7b6e0d9 commit a608607

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,9 @@ static Decomposition decomposeGEP(GEPOperator &GEP,
452452
"unsigned predicates at the moment.");
453453
const auto &[BasePtr, ConstantOffset, VariableOffsets, NW] =
454454
collectOffsets(GEP, DL);
455-
if (!BasePtr || !NW.hasNoUnsignedSignedWrap())
455+
// We support either plain gep nuw, or gep nusw with non-negative offset,
456+
// which implies gep nuw.
457+
if (!BasePtr || NW == GEPNoWrapFlags::none())
456458
return &GEP;
457459

458460
Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr));
@@ -461,11 +463,13 @@ static Decomposition decomposeGEP(GEPOperator &GEP,
461463
IdxResult.mul(Scale.getSExtValue());
462464
Result.add(IdxResult);
463465

464-
// If Op0 is signed non-negative, the GEP is increasing monotonically and
465-
// can be de-composed.
466-
if (!isKnownNonNegative(Index, DL))
467-
Preconditions.emplace_back(CmpInst::ICMP_SGE, Index,
468-
ConstantInt::get(Index->getType(), 0));
466+
if (!NW.hasNoUnsignedWrap()) {
467+
// Try to prove nuw from nusw and nneg.
468+
assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
469+
if (!isKnownNonNegative(Index, DL))
470+
Preconditions.emplace_back(CmpInst::ICMP_SGE, Index,
471+
ConstantInt::get(Index->getType(), 0));
472+
}
469473
}
470474
return Result;
471475
}

llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,7 @@ define i1 @test_nuw(ptr %p, i64 %x, i64 %y) {
702702
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]])
703703
; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
704704
; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
705-
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X]], [[GEP_Y]]
706-
; CHECK-NEXT: ret i1 [[CMP2]]
705+
; CHECK-NEXT: ret i1 true
707706
;
708707
%cmp1 = icmp ugt i64 %x, %y
709708
call void @llvm.assume(i1 %cmp1)
@@ -720,8 +719,7 @@ define i1 @test_nuw_nested(ptr %p, i64 %x, i64 %y) {
720719
; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
721720
; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1
722721
; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
723-
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]]
724-
; CHECK-NEXT: ret i1 [[CMP2]]
722+
; CHECK-NEXT: ret i1 true
725723
;
726724
%cmp1 = icmp ugt i64 %x, %y
727725
call void @llvm.assume(i1 %cmp1)

0 commit comments

Comments
 (0)