[llvm] [InstCombine] Canonicalize complex boolean expressions into ~((y | z) ^ x) via 3-input truth table (PR #149530)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 18 09:31:25 PDT 2025
================
@@ -50,6 +51,213 @@ static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS,
return Builder.CreateFCmpFMF(NewPred, LHS, RHS, FMF);
}
+/// This is to create optimal 3-variable boolean logic from truth tables.
+/// currently it supports the cases pertaining to the issue 97044. More cases
+/// can be added based on real-world justification for specific 3 input cases
+/// or with reviewer approval all 256 cases can be added (choose the
+/// canonicalizations found
+/// in x86InstCombine.cpp?)
+static Value *createLogicFromTable3Var(const std::bitset<8> &Table, Value *Op0,
+ Value *Op1, Value *Op2, Value *Root,
+ IRBuilderBase &Builder) {
+ uint8_t TruthValue = Table.to_ulong();
+ auto FoldConstant = [&](bool Val) {
+ Type *Ty = Op0->getType();
+ return Val ? ConstantInt::getTrue(Ty) : ConstantInt::getFalse(Ty);
+ };
+
+ Value *Result = nullptr;
+ switch (TruthValue) {
+ default:
+ return nullptr;
+ case 0x00: // Always FALSE
+ Result = FoldConstant(false);
+ break;
+ case 0xFF: // Always TRUE
+ Result = FoldConstant(true);
+ break;
+ case 0xE1: // ~((Op1 | Op2) ^ Op0)
+ {
+ Value *Or = Builder.CreateOr(Op1, Op2);
+ Value *Xor = Builder.CreateXor(Or, Op0);
+ Result = Builder.CreateNot(Xor);
+ } break;
+ case 0x60: // Op0 & (Op1 ^ Op2)
+ {
+ Value *Xor = Builder.CreateXor(Op1, Op2);
+ Result = Builder.CreateAnd(Op0, Xor);
+ } break;
+ case 0xD2: // ((Op1 | Op2) ^ Op0) ^ Op1
+ {
+ Value *Or = Builder.CreateOr(Op1, Op2);
+ Value *Xor1 = Builder.CreateXor(Or, Op0);
+ Result = Builder.CreateXor(Xor1, Op1);
+ } break;
+ }
+
+ return Result;
+}
+
+static std::tuple<Value *, Value *, Value *, SmallVector<Instruction *>>
----------------
dtcxzyw wrote:
Avoid returning vectors. You can pass it by reference:
```
extractThreeVariablesAndInstructions(Value *Root, SmallVectorImpl<Instruction *> & Instructions) {
}
SmallVector<Instruction *> Instructions;
extractThreeVariablesAndInstructions(&I, Instructions);
```
https://github.com/llvm/llvm-project/pull/149530
More information about the llvm-commits
mailing list