Skip to content

Commit 0310f7f

Browse files
committed
[InstCombine] Fold (add X, (sext/zext (icmp eq X, C)))
We can convert this to a select based on the `(icmp eq X, C)`, then constant fold the addition the true arm begin `(add C, (sext/zext 1))` and the false arm being `(add X, 0)` e.g - `(select (icmp eq X, C), (add C, (sext/zext 1)), (add X, 0))`. This is essentially a specialization of the only case that sees to actually show up from #89020 Closes #93840
1 parent c877eb3 commit 0310f7f

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,24 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
16941694
return BinaryOperator::CreateOr(LHS, Zext);
16951695
}
16961696

1697+
{
1698+
Value *Cond, *Ext;
1699+
Constant *C;
1700+
// (add X, (sext/zext (icmp eq X, C)))
1701+
// -> (select (icmp eq X, C), (add C, (sext/zext 1)), X)
1702+
auto CondMatcher = m_CombineAnd(
1703+
m_Value(Cond), m_ICmp(Pred, m_Deferred(A), m_ImmConstant(C)));
1704+
1705+
if (match(&I,
1706+
m_c_Add(m_Value(A),
1707+
m_CombineAnd(m_Value(Ext), m_ZExtOrSExt(CondMatcher)))) &&
1708+
Pred == ICmpInst::ICMP_EQ && Ext->hasOneUse()) {
1709+
Value *Add = isa<ZExtInst>(Ext) ? InstCombiner::AddOne(C)
1710+
: InstCombiner::SubOne(C);
1711+
return replaceInstUsesWith(I, Builder.CreateSelect(Cond, Add, A));
1712+
}
1713+
}
1714+
16971715
if (Instruction *Ashr = foldAddToAshr(I))
16981716
return Ashr;
16991717

llvm/test/Transforms/InstCombine/apint-shift.ll

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ define i23 @test11(i23 %x) {
240240

241241
define i47 @test12(i47 %X) {
242242
; CHECK-LABEL: @test12(
243-
; CHECK-NEXT: [[SH2:%.*]] = and i47 [[X:%.*]], -256
244-
; CHECK-NEXT: ret i47 [[SH2]]
243+
; CHECK-NEXT: [[SH1:%.*]] = and i47 [[X:%.*]], -256
244+
; CHECK-NEXT: ret i47 [[SH1]]
245245
;
246246
%sh1 = ashr i47 %X, 8
247247
%sh2 = shl i47 %sh1, 8
@@ -250,8 +250,8 @@ define i47 @test12(i47 %X) {
250250

251251
define <2 x i47> @test12_splat_vec(<2 x i47> %X) {
252252
; CHECK-LABEL: @test12_splat_vec(
253-
; CHECK-NEXT: [[SH2:%.*]] = and <2 x i47> [[X:%.*]], <i47 -256, i47 -256>
254-
; CHECK-NEXT: ret <2 x i47> [[SH2]]
253+
; CHECK-NEXT: [[SH1:%.*]] = and <2 x i47> [[X:%.*]], <i47 -256, i47 -256>
254+
; CHECK-NEXT: ret <2 x i47> [[SH1]]
255255
;
256256
%sh1 = ashr <2 x i47> %X, <i47 8, i47 8>
257257
%sh2 = shl <2 x i47> %sh1, <i47 8, i47 8>
@@ -564,14 +564,7 @@ define i40 @test26(i40 %A) {
564564
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9880
565565
define i177 @ossfuzz_9880(i177 %X) {
566566
; CHECK-LABEL: @ossfuzz_9880(
567-
; CHECK-NEXT: [[A:%.*]] = alloca i177, align 8
568-
; CHECK-NEXT: [[L1:%.*]] = load i177, ptr [[A]], align 4
569-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L1]], -1
570-
; CHECK-NEXT: [[B5_NEG:%.*]] = sext i1 [[TMP1]] to i177
571-
; CHECK-NEXT: [[B14:%.*]] = add i177 [[L1]], [[B5_NEG]]
572-
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i177 [[B14]], -1
573-
; CHECK-NEXT: [[B1:%.*]] = zext i1 [[TMP2]] to i177
574-
; CHECK-NEXT: ret i177 [[B1]]
567+
; CHECK-NEXT: ret i177 0
575568
;
576569
%A = alloca i177
577570
%L1 = load i177, ptr %A

llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
declare void @use.i8(i8)
55
define i8 @fold_add_zext_eq_0(i8 %x) {
66
; CHECK-LABEL: @fold_add_zext_eq_0(
7-
; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq i8 [[X:%.*]], 0
8-
; CHECK-NEXT: [[X_EQ_EXT:%.*]] = zext i1 [[X_EQ]] to i8
9-
; CHECK-NEXT: [[R:%.*]] = add i8 [[X_EQ_EXT]], [[X]]
7+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 1)
108
; CHECK-NEXT: ret i8 [[R]]
119
;
1210
%x_eq = icmp eq i8 %x, 0
@@ -19,8 +17,7 @@ define <2 x i8> @fold_add_sext_eq_4_6(<2 x i6> %xx) {
1917
; CHECK-LABEL: @fold_add_sext_eq_4_6(
2018
; CHECK-NEXT: [[X:%.*]] = zext <2 x i6> [[XX:%.*]] to <2 x i8>
2119
; CHECK-NEXT: [[X_EQ:%.*]] = icmp eq <2 x i8> [[X]], <i8 4, i8 -127>
22-
; CHECK-NEXT: [[X_EQ_EXT:%.*]] = sext <2 x i1> [[X_EQ]] to <2 x i8>
23-
; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[X_EQ_EXT]], [[X]]
20+
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X_EQ]], <2 x i8> <i8 3, i8 -128>, <2 x i8> [[X]]
2421
; CHECK-NEXT: ret <2 x i8> [[R]]
2522
;
2623
%x = zext <2 x i6> %xx to <2 x i8>

0 commit comments

Comments
 (0)