Skip to content

Commit 0c6cfb3

Browse files
committed
[InstCombine] Remove one-use requirement for add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN
Since these remove instructions, we can forgo the one-use check, as long as one of the two sexts are one-use.
1 parent 7fd0829 commit 0c6cfb3

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

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

512512
// add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN
513-
// TODO: Relax the one-use checks because we are removing an instruction?
514-
if (match(I, m_Add(m_OneUse(m_SExt(m_Value(X))),
515-
m_OneUse(m_SExt(m_Value(Y))))) &&
516-
X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType()) {
513+
if (match(I, m_Add(m_SExt(m_Value(X)), m_SExt(m_Value(Y)))) &&
514+
X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&
515+
(I->getOperand(0)->hasOneUse() || I->getOperand(1)->hasOneUse())) {
516+
517517
// Truth table for inputs and output signbits:
518518
// X:0 | X:1
519519
// -----------

llvm/test/Transforms/InstCombine/add.ll

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

1438-
; Negative test - extra use
1438+
declare void @use_sexts(i32, i32)
14391439

1440-
define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
1441-
; CHECK-LABEL: @lshr_add_use_sexts(
1440+
; Negative test
1441+
define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y, ptr %p) {
1442+
; CHECK-LABEL: @lshr_add_use_sexts_both(
14421443
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1444+
; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4
14431445
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1446+
; CHECK-NEXT: call void @use_sexts(i32 [[XS]], i32 [[YS]])
14441447
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
14451448
; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
14461449
; CHECK-NEXT: ret i32 [[R]]
14471450
;
14481451
%xs = sext i1 %x to i32
1452+
store i32 %xs, ptr %p
14491453
%ys = sext i1 %y to i32
1454+
call void @use_sexts(i32 %xs, i32 %ys)
14501455
%sub = add i32 %xs, %ys
14511456
%r = lshr i32 %sub, 31
14521457
ret i32 %r
14531458
}
14541459

1455-
; Negative test - extra use
1456-
14571460
define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
14581461
; CHECK-LABEL: @lshr_add_use_sexts(
1462+
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1463+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
1464+
; CHECK-NEXT: ret i32 [[R]]
1465+
;
1466+
%xs = sext i1 %x to i32
1467+
%ys = sext i1 %y to i32
1468+
%sub = add i32 %xs, %ys
1469+
%r = lshr i32 %sub, 31
1470+
ret i32 %r
1471+
}
1472+
1473+
; Negative test - extra use
1474+
1475+
define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {
1476+
; CHECK-LABEL: @lshr_add_use_sexts_2(
14591477
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
14601478
; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4
1461-
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1462-
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1463-
; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1479+
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
1480+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
14641481
; CHECK-NEXT: ret i32 [[R]]
14651482
;
14661483
%xs = sext i1 %x to i32
@@ -1473,11 +1490,10 @@ define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
14731490

14741491
define i32 @lshr_add_use2_sexts(i1 %x, i1 %y, ptr %p) {
14751492
; CHECK-LABEL: @lshr_add_use2_sexts(
1476-
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
14771493
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
14781494
; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
1479-
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1480-
; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
1495+
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
1496+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
14811497
; CHECK-NEXT: ret i32 [[R]]
14821498
;
14831499
%xs = sext i1 %x to i32
@@ -4033,8 +4049,8 @@ define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
40334049

40344050
define i32 @fold_sext_addition_or_disjoint(i8 %x) {
40354051
; CHECK-LABEL: @fold_sext_addition_or_disjoint(
4036-
; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX:%.*]] to i32
4037-
; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1246
4052+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4053+
; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 1246
40384054
; CHECK-NEXT: ret i32 [[R]]
40394055
;
40404056
%xx = or disjoint i8 %x, 12
@@ -4058,8 +4074,8 @@ define i32 @fold_sext_addition_fail(i8 %x) {
40584074

40594075
define i32 @fold_zext_addition_or_disjoint(i8 %x) {
40604076
; CHECK-LABEL: @fold_zext_addition_or_disjoint(
4061-
; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX:%.*]] to i32
4062-
; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1246
4077+
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
4078+
; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246
40634079
; CHECK-NEXT: ret i32 [[R]]
40644080
;
40654081
%xx = or disjoint i8 %x, 12
@@ -4070,9 +4086,9 @@ define i32 @fold_zext_addition_or_disjoint(i8 %x) {
40704086

40714087
define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
40724088
; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
4073-
; CHECK-NEXT: [[XX:%.*]] = add nuw i8 [[X:%.*]], 4
4074-
; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32
4075-
; CHECK-NEXT: ret i32 [[SE]]
4089+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4
4090+
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP1]] to i32
4091+
; CHECK-NEXT: ret i32 [[R]]
40764092
;
40774093
%xx = or disjoint i8 %x, 18
40784094
%se = zext i8 %xx to i32

0 commit comments

Comments
 (0)