[llvm] [InstCombine] Fold comparison of adding two z/sext booleans (PR #67895)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 1 03:17:53 PDT 2023
dtcxzyw wrote:
Hi! I wrote a Python script to generate the lookup table.
Python script: https://paste.ubuntu.com/p/HTqRkYJ7hT/
Generated code:
```
Instruction *ExtA, *ExtB;
if (Cmp.isEquality() &&
match(Add, m_c_Add(m_CombineAnd(m_Instruciton(ExtA), m_OneUse(m_ZExtOrSExt(m_Value(Op0)))),
m_CombineAnd(m_Instruciton(ExtB), m_OneUse(m_ZExtOrSExt(m_Value(Op1)))))) &&
Op0->getType()->isIntOrIntVectorTy(1) &&
Op1->getType()->isIntOrIntVectorTy(1) &&
C.sge(-2) && C.sle(2)) {
bool ZExtA = ExtA->getOpcode() == Instruction::ZExt;
bool ZExtB = ExtB->getOpcode() == Instruction::ZExt;
bool PredNe = Cmp.getPredicate() == CmpInst::ICMP_NE;
// (zextA, zextB, pred, val, inv) -> op
// op: 0 - false, 1 - true, 2 - and, 3 - or, 4 - xor, 5 - nand, 6 - nor, 7 - xnor, 8 - invalid
const unsigned LUT[2][2][2][5][3] = {
2 ,8 ,8 ,4 ,8 ,8 ,6 ,8 ,8 ,0 ,8 ,8 ,0 ,8 ,8 ,5 ,8 ,8 ,7 ,8 ,8 ,3 ,8 ,8 ,1 ,8 ,8 ,1 ,8 ,8 ,0 ,8 ,8 ,8 ,6 ,2 ,7 ,8 ,8 ,8 ,2 ,6 ,0 ,8 ,8 ,1 ,8 ,8 ,8 ,3 ,5 ,4 ,8 ,8 ,8 ,5 ,3 ,1 ,8 ,8 ,0 ,8 ,8 ,8 ,2 ,6 ,7 ,8 ,8 ,8 ,6 ,2 ,0 ,8 ,8 ,1 ,8 ,8 ,8 ,5 ,3 ,4 ,8 ,8 ,8 ,3 ,5 ,1 ,8 ,8 ,0 ,8 ,8 ,0 ,8 ,8 ,6 ,8 ,8 ,4 ,8 ,8 ,2 ,8 ,8 ,1 ,8 ,8 ,1 ,8 ,8 ,3 ,8 ,8 ,7 ,8 ,8 ,5 ,8 ,8 ,};
unsigned op = LUT[ZExtA][ZExtB][PredNe][C.getSExtValue() + 2][0];
if (op == 8) {
if (isFreeToInvert(Op0, Op0->hasOneUse())) {
Op0 = Builder.CreateNot(Op0);
op = LUT[ZExtA][ZExtB][PredNe][C.getSExtValue() + 2][1];
}
else {
Op1 = Builder.CreateNot(Op1);
op = LUT[ZExtA][ZExtB][PredNe][C.getSExtValue() + 2][2];
}
}
switch(op) {
case 0: return replaceInstUsesWith(Cmp, Builder.getFalse());
case 1: return replaceInstUsesWith(Cmp, Builder.getTrue());
case 2: return BinaryOperator::CreateAnd(Op0, Op1);
case 3: return BinaryOperator::CreateOr(Op0, Op1);
case 4: return BinaryOperator::CreateXor(Op0, Op1);
case 5: return BinaryOperator::CreateNot(Builder.CreateAnd(Op0, Op1));
case 6: return BinaryOperator::CreateNot(Builder.CreateOr(Op0, Op1));
case 7: return BinaryOperator::CreateNot(Builder.CreateXor(Op0, Op1));
default: llvm_unreachable("Invalid Ops");
}
}
```
Alive2: https://alive2.llvm.org/ce/z/JgcfFJ
https://github.com/llvm/llvm-project/pull/67895
More information about the llvm-commits
mailing list