Skip to content

Commit dd0245e

Browse files
authored
[InstCombine] Relax one-use requirement for add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN (#90509)
Since these remove instructions as long as at least one of X or Y is one-use, we don't need to check one-use for both.
1 parent c931ac5 commit dd0245e

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,10 +499,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
499499
}
500500

501501
// add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN
502-
// TODO: Relax the one-use checks because we are removing an instruction?
503-
if (match(I, m_Add(m_OneUse(m_SExt(m_Value(X))),
504-
m_OneUse(m_SExt(m_Value(Y))))) &&
505-
X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType()) {
502+
if (match(I, m_Add(m_SExt(m_Value(X)), m_SExt(m_Value(Y)))) &&
503+
X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&
504+
(I->getOperand(0)->hasOneUse() || I->getOperand(1)->hasOneUse())) {
505+
506506
// Truth table for inputs and output signbits:
507507
// X:0 | X:1
508508
// -----------

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,15 +1435,28 @@ define i32 @and31_add_sexts(i1 %x, i1 %y) {
14351435
ret i32 %r
14361436
}
14371437

1438-
; Negative test - extra use
1439-
14401438
define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
14411439
; CHECK-LABEL: @lshr_add_use_sexts(
1440+
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1441+
; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
1442+
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
1443+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
1444+
; CHECK-NEXT: ret i32 [[R]]
1445+
;
1446+
%xs = sext i1 %x to i32
1447+
%ys = sext i1 %y to i32
1448+
store i32 %ys, ptr %p
1449+
%sub = add i32 %xs, %ys
1450+
%r = lshr i32 %sub, 31
1451+
ret i32 %r
1452+
}
1453+
1454+
define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {
1455+
; CHECK-LABEL: @lshr_add_use_sexts_2(
14421456
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
14431457
; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4
1444-
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1445-
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1446-
; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1458+
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
1459+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
14471460
; CHECK-NEXT: ret i32 [[R]]
14481461
;
14491462
%xs = sext i1 %x to i32
@@ -1456,18 +1469,20 @@ define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
14561469

14571470
; Negative test - extra use
14581471

1459-
define i32 @lshr_add_use2_sexts(i1 %x, i1 %y, ptr %p) {
1460-
; CHECK-LABEL: @lshr_add_use2_sexts(
1472+
declare void @use_sexts(i32, i32)
1473+
1474+
define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) {
1475+
; CHECK-LABEL: @lshr_add_use_sexts_both(
14611476
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
14621477
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1463-
; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
1478+
; CHECK-NEXT: call void @use_sexts(i32 [[XS]], i32 [[YS]])
14641479
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
14651480
; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
14661481
; CHECK-NEXT: ret i32 [[R]]
14671482
;
14681483
%xs = sext i1 %x to i32
14691484
%ys = sext i1 %y to i32
1470-
store i32 %ys, ptr %p
1485+
call void @use_sexts(i32 %xs, i32 %ys)
14711486
%sub = add i32 %xs, %ys
14721487
%r = lshr i32 %sub, 31
14731488
ret i32 %r

0 commit comments

Comments
 (0)