Skip to content

Commit 865c1fd

Browse files
authored
[InstCombine] Preserve NSW flags for neg instructions (#72548)
Alive2: https://alive2.llvm.org/ce/z/F9HG3M This missed optimization is discovered with the help of AliveToolkit/alive2#962.
1 parent 5353d3f commit 865c1fd

File tree

3 files changed

+13
-13
lines changed

3 files changed

+13
-13
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
14331433
// sdiv Op0, (sext i1 X) --> -Op0 (because if X is 0, the op is undefined)
14341434
if (match(Op1, m_AllOnes()) ||
14351435
(match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)))
1436-
return BinaryOperator::CreateNeg(Op0);
1436+
return BinaryOperator::CreateNSWNeg(Op0);
14371437

14381438
// X / INT_MIN --> X == INT_MIN
14391439
if (match(Op1, m_SignMask()))
@@ -1456,7 +1456,7 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
14561456
Constant *NegPow2C = ConstantExpr::getNeg(cast<Constant>(Op1));
14571457
Constant *C = ConstantExpr::getExactLogBase2(NegPow2C);
14581458
Value *Ashr = Builder.CreateAShr(Op0, C, I.getName() + ".neg", true);
1459-
return BinaryOperator::CreateNeg(Ashr);
1459+
return BinaryOperator::CreateNSWNeg(Ashr);
14601460
}
14611461
}
14621462

llvm/test/Transforms/InstCombine/div.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ define i32 @test2(i32 %A) {
2222

2323
define i32 @sdiv_by_minus1(i32 %A) {
2424
; CHECK-LABEL: @sdiv_by_minus1(
25-
; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]]
25+
; CHECK-NEXT: [[B:%.*]] = sub nsw i32 0, [[A:%.*]]
2626
; CHECK-NEXT: ret i32 [[B]]
2727
;
2828
%B = sdiv i32 %A, -1
@@ -31,7 +31,7 @@ define i32 @sdiv_by_minus1(i32 %A) {
3131

3232
define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) {
3333
; CHECK-LABEL: @sdiv_by_minus1_vec(
34-
; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i64> zeroinitializer, [[X:%.*]]
34+
; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]]
3535
; CHECK-NEXT: ret <2 x i64> [[DIV]]
3636
;
3737
%div = sdiv <2 x i64> %x, <i64 -1, i64 -1>
@@ -48,7 +48,7 @@ define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) {
4848

4949
define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {
5050
; CHECK-LABEL: @sdiv_by_sext_minus1(
51-
; CHECK-NEXT: [[DIV:%.*]] = sub i32 0, [[Y:%.*]]
51+
; CHECK-NEXT: [[DIV:%.*]] = sub nsw i32 0, [[Y:%.*]]
5252
; CHECK-NEXT: ret i32 [[DIV]]
5353
;
5454
%sext = sext i1 %x to i32
@@ -58,7 +58,7 @@ define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {
5858

5959
define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) {
6060
; CHECK-LABEL: @sdiv_by_sext_minus1_vec(
61-
; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i32> zeroinitializer, [[Y:%.*]]
61+
; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i32> zeroinitializer, [[Y:%.*]]
6262
; CHECK-NEXT: ret <2 x i32> [[DIV]]
6363
;
6464
%sext = sext <2 x i1> %x to <2 x i32>
@@ -1308,8 +1308,8 @@ define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) {
13081308
define i1 @sdiv_one_icmpeq_one(i32 %x) {
13091309
; CHECK-LABEL: @sdiv_one_icmpeq_one(
13101310
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
1311-
; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X_FR]], 1
1312-
; CHECK-NEXT: ret i1 [[B]]
1311+
; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], 1
1312+
; CHECK-NEXT: ret i1 [[B1]]
13131313
;
13141314
%A = sdiv i32 1, %x
13151315
%B = icmp eq i32 %A, 1
@@ -1319,8 +1319,8 @@ define i1 @sdiv_one_icmpeq_one(i32 %x) {
13191319
define i1 @sdiv_one_icmpeq_negone(i32 %x) {
13201320
; CHECK-LABEL: @sdiv_one_icmpeq_negone(
13211321
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
1322-
; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X_FR]], -1
1323-
; CHECK-NEXT: ret i1 [[B]]
1322+
; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X_FR]], -1
1323+
; CHECK-NEXT: ret i1 [[B1]]
13241324
;
13251325
%A = sdiv i32 1, %x
13261326
%B = icmp eq i32 %A, -1

llvm/test/Transforms/InstCombine/sdiv-exact-by-negative-power-of-two.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ define <2 x i8> @t2_vec_splat(<2 x i8> %x) {
3838
define <2 x i8> @t3_vec(<2 x i8> %x) {
3939
; CHECK-LABEL: @t3_vec(
4040
; CHECK-NEXT: [[DIV_NEG:%.*]] = ashr exact <2 x i8> [[X:%.*]], <i8 5, i8 4>
41-
; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i8> zeroinitializer, [[DIV_NEG]]
41+
; CHECK-NEXT: [[DIV:%.*]] = sub nsw <2 x i8> zeroinitializer, [[DIV_NEG]]
4242
; CHECK-NEXT: ret <2 x i8> [[DIV]]
4343
;
4444
%div = sdiv exact <2 x i8> %x, <i8 -32, i8 -16>
@@ -76,8 +76,8 @@ define i8 @prove_exact_with_high_mask(i8 %x, i8 %y) {
7676

7777
define i8 @prove_exact_with_high_mask_limit(i8 %x, i8 %y) {
7878
; CHECK-LABEL: @prove_exact_with_high_mask_limit(
79-
; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 5
80-
; CHECK-NEXT: [[D:%.*]] = sub nsw i8 0, [[A]]
79+
; CHECK-NEXT: [[D_NEG:%.*]] = ashr i8 [[X:%.*]], 5
80+
; CHECK-NEXT: [[D:%.*]] = sub nsw i8 0, [[D_NEG]]
8181
; CHECK-NEXT: ret i8 [[D]]
8282
;
8383
%a = and i8 %x, -32

0 commit comments

Comments
 (0)