Skip to content

Commit 8e516d4

Browse files
authored
[InstCombine] Infer nuw flags for C-(X+C2) -> (C-C2)-X (#72373)
This patch improves https://reviews.llvm.org/D152068 by inferring NUW flags for sub insts. It is worth noting that we don't need to check overflow for `C-C2`. Alive2: https://alive2.llvm.org/ce/z/uutGpS This missed optimization is discovered with the help of AliveToolkit/alive2#962.
1 parent 4fdc289 commit 8e516d4

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,14 +2111,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
21112111

21122112
// C-(X+C2) --> (C-C2)-X
21132113
if (match(Op1, m_Add(m_Value(X), m_ImmConstant(C2)))) {
2114-
// C-C2 never overflow, and C-(X+C2), (X+C2) has NSW
2115-
// => (C-C2)-X can have NSW
2114+
// C-C2 never overflow, and C-(X+C2), (X+C2) has NSW/NUW
2115+
// => (C-C2)-X can have NSW/NUW
21162116
bool WillNotSOV = willNotOverflowSignedSub(C, C2, I);
21172117
BinaryOperator *Res =
21182118
BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
21192119
auto *OBO1 = cast<OverflowingBinaryOperator>(Op1);
21202120
Res->setHasNoSignedWrap(I.hasNoSignedWrap() && OBO1->hasNoSignedWrap() &&
21212121
WillNotSOV);
2122+
Res->setHasNoUnsignedWrap(I.hasNoUnsignedWrap() &&
2123+
OBO1->hasNoUnsignedWrap());
21222124
return Res;
21232125
}
21242126
}

llvm/test/Transforms/InstCombine/addsub-constant-folding.ll

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,24 @@ define i8 @add_nsw_const_const_sub_nsw_ov(i8 %arg) {
175175

176176
define i8 @add_nuw_const_const_sub_nuw(i8 %arg) {
177177
; CHECK-LABEL: @add_nuw_const_const_sub_nuw(
178-
; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]]
178+
; CHECK-NEXT: [[T1:%.*]] = sub nuw i8 -128, [[ARG:%.*]]
179179
; CHECK-NEXT: ret i8 [[T1]]
180180
;
181181
%t0 = add nuw i8 %arg, 1
182182
%t1 = sub nuw i8 -127, %t0
183183
ret i8 %t1
184184
}
185185

186+
define i8 @add_nuw_const_const_sub(i8 %arg) {
187+
; CHECK-LABEL: @add_nuw_const_const_sub(
188+
; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]]
189+
; CHECK-NEXT: ret i8 [[T1]]
190+
;
191+
%t0 = add nuw i8 %arg, 1
192+
%t1 = sub i8 -127, %t0
193+
ret i8 %t1
194+
}
195+
186196
define i8 @add_const_const_sub_nuw(i8 %arg) {
187197
; CHECK-LABEL: @add_const_const_sub_nuw(
188198
; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]]

0 commit comments

Comments
 (0)