[llvm] [SPIRV] Support additional comparison predicates for i1 types (PR #174585)
Juan Manuel Martinez CaamaƱo via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 7 05:47:46 PST 2026
================
@@ -151,7 +152,79 @@ void SPIRVRegularizer::runLowerConstExpr(Function &F) {
}
}
+static Instruction *createLogicalOp(Value *Op1, Value *Op2, bool UseAnd,
+ Constant *TrueVal,
+ BasicBlock::iterator InsertPt) {
+ auto *NotOp2 =
+ BinaryOperator::Create(Instruction::Xor, Op2, TrueVal, "", InsertPt);
+ return BinaryOperator::Create(UseAnd ? Instruction::And : Instruction::Or,
+ Op1, NotOp2, "", InsertPt);
+}
+
+// Lower i1 comparisons with certain predicates to logical operations.
+// The backend treats i1 as boolean values, and SPIR-V only allows logical
+// operations for boolean values. This function lowers i1 comparisons with
+// certain predicates to logical operations to generate valid SPIR-V.
+void SPIRVRegularizer::runLowerI1Comparisons(Function &F) {
+ LLVMContext &Ctx = F.getContext();
+
+ for (auto &I : make_early_inc_range(instructions(F))) {
+ auto *Cmp = dyn_cast<ICmpInst>(&I);
+ if (!Cmp)
+ continue;
+
+ bool IsI1 = Cmp->getOperand(0)->getType()->isIntegerTy(1);
+ if (!IsI1)
+ continue;
+
+ auto Pred = Cmp->getPredicate();
+ bool IsTargetPred =
+ Pred >= ICmpInst::ICMP_UGT && Pred <= ICmpInst::ICMP_SLE;
+ if (!IsTargetPred)
+ continue;
+
+ Value *P = Cmp->getOperand(0);
+ Value *Q = Cmp->getOperand(1);
+ auto *TrueVal = ConstantInt::getTrue(Ctx);
+
+ Instruction *Result = nullptr;
+ switch (Pred) {
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SLT:
+ // Result = p & !q
+ Result =
+ createLogicalOp(P, Q, /*UseAnd=*/true, TrueVal, Cmp->getIterator());
+ break;
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SGT:
+ // Result = q & !p
+ Result =
+ createLogicalOp(Q, P, /*UseAnd=*/true, TrueVal, Cmp->getIterator());
+ break;
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SGE:
+ // Result = q | !p
+ Result =
+ createLogicalOp(Q, P, /*UseAnd=*/false, TrueVal, Cmp->getIterator());
+ break;
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SLE:
+ // Result = p | !q
+ Result =
+ createLogicalOp(P, Q, /*UseAnd=*/false, TrueVal, Cmp->getIterator());
+ break;
+ default:
+ llvm_unreachable("Unexpected predicate");
+ }
+
+ // Replace all uses and erase the old instruction
+ Cmp->replaceAllUsesWith(Result);
+ Cmp->eraseFromParent();
----------------
jmmartinez wrote:
```suggestion
Result->takeName(Cmp);
Cmp->replaceAllUsesWith(Result);
Cmp->eraseFromParent();
```
https://github.com/llvm/llvm-project/pull/174585
More information about the llvm-commits
mailing list