[llvm] 047ddbf - [SPIRV] Added support for the constrained comparison intrinsics (#157439)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 28 05:42:20 PDT 2025
Author: Subash B
Date: 2025-09-28T05:42:16-07:00
New Revision: 047ddbf263f6e64c6ec1ef148596661d28544e3a
URL: https://github.com/llvm/llvm-project/commit/047ddbf263f6e64c6ec1ef148596661d28544e3a
DIFF: https://github.com/llvm/llvm-project/commit/047ddbf263f6e64c6ec1ef148596661d28544e3a.diff
LOG: [SPIRV] Added support for the constrained comparison intrinsics (#157439)
Added SPIR-V support for constrained floating-point comparison
intrinsics (fcmp, fcmps) with lowering and tests.
Added:
llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
index 2b34f61fa2434..4e4e6fb4ab791 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
@@ -335,6 +335,21 @@ static void lowerFunnelShifts(IntrinsicInst *FSHIntrinsic) {
FSHIntrinsic->setCalledFunction(FSHFunc);
}
+static void lowerConstrainedFPCmpIntrinsic(
+ ConstrainedFPCmpIntrinsic *ConstrainedCmpIntrinsic,
+ SmallVector<Instruction *> &EraseFromParent) {
+ if (!ConstrainedCmpIntrinsic)
+ return;
+ // Extract the floating-point values being compared
+ Value *LHS = ConstrainedCmpIntrinsic->getArgOperand(0);
+ Value *RHS = ConstrainedCmpIntrinsic->getArgOperand(1);
+ FCmpInst::Predicate Pred = ConstrainedCmpIntrinsic->getPredicate();
+ IRBuilder<> Builder(ConstrainedCmpIntrinsic);
+ Value *FCmp = Builder.CreateFCmp(Pred, LHS, RHS);
+ ConstrainedCmpIntrinsic->replaceAllUsesWith(FCmp);
+ EraseFromParent.push_back(dyn_cast<Instruction>(ConstrainedCmpIntrinsic));
+}
+
static void lowerExpectAssume(IntrinsicInst *II) {
// If we cannot use the SPV_KHR_expect_assume extension, then we need to
// ignore the intrinsic and move on. It should be removed later on by LLVM.
@@ -376,6 +391,7 @@ static bool toSpvLifetimeIntrinsic(IntrinsicInst *II, Intrinsic::ID NewID) {
bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
bool Changed = false;
const SPIRVSubtarget &STI = TM.getSubtarget<SPIRVSubtarget>(*F);
+ SmallVector<Instruction *> EraseFromParent;
for (BasicBlock &BB : *F) {
for (Instruction &I : make_early_inc_range(BB)) {
auto Call = dyn_cast<CallInst>(&I);
@@ -423,9 +439,17 @@ bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
lowerPtrAnnotation(II);
Changed = true;
break;
+ case Intrinsic::experimental_constrained_fcmp:
+ case Intrinsic::experimental_constrained_fcmps:
+ lowerConstrainedFPCmpIntrinsic(dyn_cast<ConstrainedFPCmpIntrinsic>(II),
+ EraseFromParent);
+ Changed = true;
+ break;
}
}
}
+ for (auto *I : EraseFromParent)
+ I->eraseFromParent();
return Changed;
}
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll
new file mode 100644
index 0000000000000..49bb8eac10be8
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll
@@ -0,0 +1,56 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpFOrdEqual
+; CHECK-DAG: OpFOrdGreaterThan
+; CHECK-DAG: OpFOrdGreaterThanEqual
+; CHECK-DAG: OpFOrdLessThan
+; CHECK-DAG: OpFOrdLessThanEqual
+; CHECK-DAG: OpFOrdNotEqual
+; CHECK-DAG: OpOrdered
+; CHECK-DAG: OpFUnordEqual
+; CHECK-DAG: OpFUnordGreaterThan
+; CHECK-DAG: OpFUnordGreaterThanEqual
+; CHECK-DAG: OpFUnordLessThan
+; CHECK-DAG: OpFUnordLessThanEqual
+; CHECK-DAG: OpFUnordNotEqual
+; CHECK-DAG: OpUnordered
+
+define dso_local spir_kernel void @test(float %a){
+entry:
+ %cmp = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"oeq", metadata !"fpexcept.strict")
+ %cmp1 = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"ogt", metadata !"fpexcept.strict")
+ %cmp2 = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"oge", metadata !"fpexcept.strict")
+ %cmp3 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"olt", metadata !"fpexcept.strict")
+ %cmp4 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ole", metadata !"fpexcept.strict")
+ %cmp5 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"one", metadata !"fpexcept.strict")
+ %cmp6 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ord", metadata !"fpexcept.strict")
+ %cmp7 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ueq", metadata !"fpexcept.strict")
+ %cmp8 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ugt", metadata !"fpexcept.strict")
+ %cmp9 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"uge", metadata !"fpexcept.strict")
+ %cmp10 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ult", metadata !"fpexcept.strict")
+ %cmp11 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ule", metadata !"fpexcept.strict")
+ %cmp12 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"une", metadata !"fpexcept.strict")
+ %cmp13 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"uno", metadata !"fpexcept.strict")
+
+ %or1 = or i1 %cmp, %cmp1
+ %or2 = or i1 %or1, %cmp2
+ %or3 = or i1 %or2, %cmp3
+ %or4 = or i1 %or3, %cmp4
+ %or5 = or i1 %or4, %cmp5
+ %or6 = or i1 %or5, %cmp6
+ %or7 = or i1 %or6, %cmp7
+ %or8 = or i1 %or7, %cmp8
+ %or9 = or i1 %or8, %cmp9
+ %or10 = or i1 %or9, %cmp10
+ %or11 = or i1 %or10, %cmp11
+ %or12 = or i1 %or11, %cmp12
+ %or13 = or i1 %or12, %cmp13
+ br i1 %or13, label %true_block, label %false_block
+true_block:
+ ret void
+false_block:
+ ret void
+}
+declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata)
+declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)
More information about the llvm-commits
mailing list