Skip to content

Commit 44f1ddc

Browse files
committed
[InstCombine] Refine nuw propagation in OptimizePointerDifference
1 parent c93e3b7 commit 44f1ddc

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,10 +2164,13 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
21642164

21652165
// If this is a single inbounds GEP and the original sub was nuw,
21662166
// then the final multiplication is also nuw.
2167-
if (auto *I = dyn_cast<Instruction>(Result))
2167+
if (auto *I = dyn_cast<OverflowingBinaryOperator>(Result))
21682168
if (IsNUW && match(Offset2, m_Zero()) && Base.LHSNW.isInBounds() &&
2169-
I->getOpcode() == Instruction::Mul)
2170-
I->setHasNoUnsignedWrap();
2169+
I->hasNoSignedWrap() && !I->hasNoUnsignedWrap() &&
2170+
((I->getOpcode() == Instruction::Mul &&
2171+
match(I->getOperand(1), m_NonNegative())) ||
2172+
I->getOpcode() == Instruction::Shl))
2173+
cast<Instruction>(I)->setHasNoUnsignedWrap();
21712174

21722175
// If we have a 2nd GEP of the same base pointer, subtract the offsets.
21732176
// If both GEPs are inbounds, then the subtract does not have signed overflow.

llvm/test/Transforms/InstCombine/sub-gep.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ define <2 x i64> @splat_geps_multiple(ptr %base, i64 %idx0, <2 x i64> %idx1, <2
10921092

10931093
define i64 @nuw_ptrdiff_shl_nsw(ptr %base, i64 %idx) {
10941094
; CHECK-LABEL: @nuw_ptrdiff_shl_nsw(
1095-
; CHECK-NEXT: [[OFFSET:%.*]] = shl nsw i64 [[IDX:%.*]], 3
1095+
; CHECK-NEXT: [[OFFSET:%.*]] = shl nuw nsw i64 [[IDX:%.*]], 3
10961096
; CHECK-NEXT: ret i64 [[OFFSET]]
10971097
;
10981098
%offset = shl nsw i64 %idx, 3
@@ -1131,7 +1131,7 @@ define i64 @nuw_ptrdiff_mul_nsw_nneg_scale(ptr %base, i64 %idx) {
11311131

11321132
define i64 @nuw_ptrdiff_mul_nsw_unknown_scale(ptr %base, i64 %idx, i64 %scale) {
11331133
; CHECK-LABEL: @nuw_ptrdiff_mul_nsw_unknown_scale(
1134-
; CHECK-NEXT: [[OFFSET:%.*]] = mul nuw nsw i64 [[IDX:%.*]], [[SCALE:%.*]]
1134+
; CHECK-NEXT: [[OFFSET:%.*]] = mul nsw i64 [[IDX:%.*]], [[SCALE:%.*]]
11351135
; CHECK-NEXT: ret i64 [[OFFSET]]
11361136
;
11371137
%offset = mul nsw i64 %idx, %scale

0 commit comments

Comments
 (0)