Add instcombine transform A - B + B << 1 --> A + B
Details
Details
Diff Detail
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
| llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | ||
|---|---|---|
| 1396 | This can be make dramatically more generic: Something along the following lines: auto ScaleConst = [&](std::optional<unsigned> Opc,
const APInt *C) -> std::optional<APInt> {
if (!Opc)
return APInt::getZero(BitWidth);
if (Opc == Instruction::Mul)
return *C;
if (Opc == Instruction::Shl)
return APInt::getOne(BitWidth).shl(*C);
return std::nullopt;
};
// A - B case
// Todo: A + B case.
if(match(m_Sub(m_Value(A), m_Value(B1))) &&
match(m_c_Add(m_Specific(A), m_Value(B2))) {
std::optional<APInt> C1, C2;
std::optional<unsigned> Opc1, Opc2;
Value * Mul1, *Mul2;
if (match(B1, m_c_BinOp(Opc1, m_Value(D), m_APInt(MatchC1))) &&
match(B2, m_c_BinOp(Opc2, m_Specific(D), m_APInt(MatchC2)))) {
C1 = ScaleConst(Opc1, MatchC1);
C2 = ScaleConst(Opc2, MatchC2);
} else if (match(B1, m_c_BinOp(Opc1, m_Specific(B2), m_APInt(MatchC1)))) {
C1 = ScaleConst(Opc1, MatchC1);
C2 = ScaleConst(Opc2, MatchC2);
D = B2;
} else if (match(B2, m_c_BinOp(Opc2, m_Specific(B1), m_APInt(MatchC2)))) {
C1 = ScaleConst(Opc1, MatchC1);
C2 = ScaleConst(Opc2, MatchC2);
D = B1;
}
// Result if Add(A, (C2 - C1) * D
} | |
| llvm/test/Transforms/InstCombine/add.ll | ||
| 2945 | Can you split the creation of new tests to a new patch (w.o the new instcombe logic) so we can see the dif generated. | |
clang-format not found in user’s local PATH; not linting file.