Skip to content

Commit d040ee7

Browse files
committed
[InstCombine] Combine or-disjoint (and->mul), (and->mul) to and->mul
Change-Id: I0bc0be96050803f6f5ce303e82e1ad758f830d7d
1 parent 1688c30 commit d040ee7

File tree

2 files changed

+104
-4
lines changed

2 files changed

+104
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -3643,6 +3643,27 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36433643
foldAddLikeCommutative(I.getOperand(1), I.getOperand(0),
36443644
/*NSW=*/true, /*NUW=*/true))
36453645
return R;
3646+
3647+
Value *LHSOp = nullptr, *RHSOp = nullptr;
3648+
const APInt *LHSConst = nullptr, *RHSConst = nullptr;
3649+
3650+
// ((X & C1) * D) + ((X & C2) * D) -> (X & (C1 + C2) * D)
3651+
if (match(I.getOperand(0), m_Mul(m_Value(LHSOp), m_APInt(LHSConst))) &&
3652+
match(I.getOperand(1), m_Mul(m_Value(RHSOp), m_APInt(RHSConst))) &&
3653+
LHSConst == RHSConst) {
3654+
Value *LHSBase = nullptr, *RHSBase = nullptr;
3655+
const APInt *LHSMask = nullptr, *RHSMask = nullptr;
3656+
if (match(LHSOp, m_And(m_Value(LHSBase), m_APInt(LHSMask))) &&
3657+
match(RHSOp, m_And(m_Value(RHSBase), m_APInt(RHSMask))) &&
3658+
LHSBase == RHSBase &&
3659+
((*LHSMask & *RHSMask) == APInt::getZero(LHSMask->getBitWidth()))) {
3660+
auto NewAnd = Builder.CreateAnd(
3661+
LHSBase, ConstantInt::get(LHSOp->getType(), (*LHSMask + *RHSMask)));
3662+
3663+
return BinaryOperator::CreateMul(
3664+
NewAnd, ConstantInt::get(NewAnd->getType(), *LHSConst));
3665+
}
3666+
}
36463667
}
36473668

36483669
Value *X, *Y;

llvm/test/Transforms/InstCombine/or.ll

+83-4
Original file line numberDiff line numberDiff line change
@@ -1281,10 +1281,10 @@ define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
12811281
; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31>
12821282
; CHECK-NEXT: ret <16 x i1> [[TMP3]]
12831283
;
1284-
%tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>
1285-
%tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>
1286-
%tmp3 = or <16 x i1> %tmp, %tmp2
1287-
ret <16 x i1> %tmp3
1284+
%out = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>
1285+
%out2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>
1286+
%out3 = or <16 x i1> %out, %out2
1287+
ret <16 x i1> %out3
12881288
}
12891289

12901290
; This would infinite loop because it reaches a transform
@@ -2035,3 +2035,82 @@ define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {
20352035
%or1 = or i32 %xor, %yy
20362036
ret i32 %or1
20372037
}
2038+
2039+
define i32 @or_combine_mul_and1(i32 %in) {
2040+
; CHECK-LABEL: @or_combine_mul_and1(
2041+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 6
2042+
; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
2043+
; CHECK-NEXT: ret i32 [[OUT]]
2044+
;
2045+
%bitop0 = and i32 %in, 2
2046+
%out0 = mul i32 %bitop0, 72
2047+
%bitop1 = and i32 %in, 4
2048+
%out1 = mul i32 %bitop1, 72
2049+
%out = or disjoint i32 %out0, %out1
2050+
ret i32 %out
2051+
}
2052+
2053+
define i32 @or_combine_mul_and2(i32 %in) {
2054+
; CHECK-LABEL: @or_combine_mul_and2(
2055+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 10
2056+
; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
2057+
; CHECK-NEXT: ret i32 [[OUT]]
2058+
;
2059+
%bitop0 = and i32 %in, 2
2060+
%out0 = mul i32 %bitop0, 72
2061+
%bitop1 = and i32 %in, 8
2062+
%out1 = mul i32 %bitop1, 72
2063+
%out = or disjoint i32 %out0, %out1
2064+
ret i32 %out
2065+
}
2066+
2067+
define i32 @or_combine_mul_and_diff_factor(i32 %in) {
2068+
; CHECK-LABEL: @or_combine_mul_and_diff_factor(
2069+
; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 2
2070+
; CHECK-NEXT: [[TMP0:%.*]] = mul nuw nsw i32 [[BITOP0]], 36
2071+
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 4
2072+
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i32 [[BITOP1]], 72
2073+
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TMP0]], [[TMP1]]
2074+
; CHECK-NEXT: ret i32 [[OUT]]
2075+
;
2076+
%bitop0 = and i32 %in, 2
2077+
%out0 = mul i32 %bitop0, 36
2078+
%bitop1 = and i32 %in, 4
2079+
%out1 = mul i32 %bitop1, 72
2080+
%out = or disjoint i32 %out0, %out1
2081+
ret i32 %out
2082+
}
2083+
2084+
define i32 @or_combine_mul_and_diff_base(i32 %in, i32 %in1) {
2085+
; CHECK-LABEL: @or_combine_mul_and_diff_base(
2086+
; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 2
2087+
; CHECK-NEXT: [[TMP0:%.*]] = mul nuw nsw i32 [[BITOP0]], 72
2088+
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN1:%.*]], 4
2089+
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i32 [[BITOP1]], 72
2090+
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TMP0]], [[TMP1]]
2091+
; CHECK-NEXT: ret i32 [[OUT]]
2092+
;
2093+
%bitop0 = and i32 %in, 2
2094+
%out0 = mul i32 %bitop0, 72
2095+
%bitop1 = and i32 %in1, 4
2096+
%out1 = mul i32 %bitop1, 72
2097+
%out = or disjoint i32 %out0, %out1
2098+
ret i32 %out
2099+
}
2100+
2101+
define i32 @or_combine_mul_and_decomposed(i32 %in) {
2102+
; CHECK-LABEL: @or_combine_mul_and_decomposed(
2103+
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[IN:%.*]] to i1
2104+
; CHECK-NEXT: [[OUT0:%.*]] = select i1 [[TMP2]], i32 72, i32 0
2105+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN]], 4
2106+
; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
2107+
; CHECK-NEXT: [[OUT1:%.*]] = or disjoint i32 [[OUT0]], [[OUT]]
2108+
; CHECK-NEXT: ret i32 [[OUT1]]
2109+
;
2110+
%bitop0 = and i32 %in, 1
2111+
%out0 = mul i32 %bitop0, 72
2112+
%bitop1 = and i32 %in, 4
2113+
%out1 = mul i32 %bitop1, 72
2114+
%out = or disjoint i32 %out0, %out1
2115+
ret i32 %out
2116+
}

0 commit comments

Comments
 (0)