[llvm] Add PreLegalizer pattern matching for degrees GL extension (PR #216506)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 16 10:54:20 PDT 2026
https://github.com/albertbolt1 updated https://github.com/llvm/llvm-project/pull/216506
>From e60fac977acc6fcc7ece0e50dc2a69ee8537c195 Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sun, 16 Aug 2026 01:04:30 +0530
Subject: [PATCH 1/5] Added required code and test case
---
llvm/lib/Target/SPIRV/SPIRVCombine.td | 10 +++-
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 49 +++++++++++++++++++
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h | 2 +
.../hlsl-intrinsics/degrees_nointrinsic.ll | 14 ++++++
4 files changed, 73 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombine.td b/llvm/lib/Target/SPIRV/SPIRVCombine.td
index 7d69465de4ffb..a4ed0b5161d81 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombine.td
+++ b/llvm/lib/Target/SPIRV/SPIRVCombine.td
@@ -34,10 +34,16 @@ def matrix_multiply_lowering
[{ return Helper.matchMatrixMultiply(*${root}); }]),
(apply [{ Helper.applyMatrixMultiply(*${root}); }])>;
+def degrees_lowering
+ : GICombineRule<(defs root:$root),
+ (match (wip_match_opcode G_FMUL):$root,
+ [{ return Helper.matchDegrees(*${root}); }]),
+ (apply [{ Helper.applyDegrees(*${root}); }])>;
+
def SPIRVPreLegalizerCombiner
: GICombiner<"SPIRVPreLegalizerCombinerImpl",
[vector_length_sub_to_distance_lowering,
vector_select_to_faceforward_lowering,
- matrix_transpose_lowering, matrix_multiply_lowering]> {
+ matrix_transpose_lowering, matrix_multiply_lowering, degrees_lowering]> {
let CombineAllMethodName = "tryCombineAllImpl";
-}
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 0882970895452..58ea761c2769a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -381,3 +381,52 @@ void SPIRVCombinerHelper::applyMatrixMultiply(MachineInstr &MI) const {
Builder.buildBuildVector(ResReg, ResultScalars);
MI.eraseFromParent();
}
+
+bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
+ if (MI.getOpcode() != TargetOpcode::G_FMUL)
+ return false;
+ Register Op1 = MI.getOperand(1).getReg();
+ Register Op2 = MI.getOperand(2).getReg();
+ MachineInstr *Op1Def = MRI.getVRegDef(Op1);
+ MachineInstr *Op2Def = MRI.getVRegDef(Op2);
+
+ if (!Op1Def || !Op2Def)
+ return false;
+
+ if (Op1Def->getOpcode() != TargetOpcode::G_FCONSTANT && Op2Def->getOpcode() != TargetOpcode::G_FCONSTANT)
+ return false;
+
+ MachineInstr *constantMachineInstruction = (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op1Def : Op2Def;
+ MachineOperand &ConstantOperand = constantMachineInstruction->getOperand(1);
+
+ if (!ConstantOperand.isFPImm())
+ return false;
+
+ const ConstantFP *Constant = ConstantOperand.getFPImm();
+ const APFloat &Val = Constant->getValueAPF();
+ APFloat Expected(180.0 / std::acos(-1.0));
+ bool LostInfo = false;
+ Expected.convert(Val.getSemantics(),
+ APFloat::rmNearestTiesToEven,
+ &LostInfo);
+
+ if (Expected.compare(Val) != APFloat::cmpEqual)
+ return false;
+
+ return true;
+}
+
+void SPIRVCombinerHelper::applyDegrees(MachineInstr &MI) const {
+ Register ResultReg = MI.getOperand(0).getReg();
+ Register Op1 = MI.getOperand(1).getReg();
+ Register Op2 = MI.getOperand(2).getReg();
+ MachineInstr *Op1Def = MRI.getVRegDef(Op1);
+ MachineInstr *Op2Def = MRI.getVRegDef(Op2);
+ Register nonConstantReg = (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op2 : Op1;
+
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildIntrinsic(Intrinsic::spv_degrees, ResultReg)
+ .addUse(nonConstantReg);
+
+ MI.eraseFromParent();
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
index 19e2a6901b8f0..3a25940b61c14 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
@@ -37,6 +37,8 @@ class SPIRVCombinerHelper : public CombinerHelper {
void applyMatrixTranspose(MachineInstr &MI) const;
bool matchMatrixMultiply(MachineInstr &MI) const;
void applyMatrixMultiply(MachineInstr &MI) const;
+ bool matchDegrees(MachineInstr &MI) const;
+ void applyDegrees(MachineInstr &MI) const;
private:
SPIRVTypeInst getDotProductVectorType(Register ResReg, uint32_t K,
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll
new file mode 100644
index 0000000000000..4554559ca6b14
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+
+; CHECK-LABEL: Begin function fmul_to_degrees
+; CHECK: %[[#arg:]] = OpFunctionParameter %[[#float_32]]
+; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Degrees %[[#arg]]
+
+define noundef float @fmul_to_degrees(float noundef %x) {
+entry:
+ %mul = fmul reassoc nnan ninf nsz arcp afn float %x, f0x42652EE1
+ ret float %mul
+}
\ No newline at end of file
>From 368ceed2146cd645b2c3b36663d44d41415bfd90 Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sun, 16 Aug 2026 01:17:48 +0530
Subject: [PATCH 2/5] Added required code and test case
---
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 58ea761c2769a..0da5ab6337ebb 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -393,10 +393,12 @@ bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
if (!Op1Def || !Op2Def)
return false;
- if (Op1Def->getOpcode() != TargetOpcode::G_FCONSTANT && Op2Def->getOpcode() != TargetOpcode::G_FCONSTANT)
+ if (Op1Def->getOpcode() != TargetOpcode::G_FCONSTANT &&
+ Op2Def->getOpcode() != TargetOpcode::G_FCONSTANT)
return false;
- MachineInstr *constantMachineInstruction = (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op1Def : Op2Def;
+ MachineInstr *constantMachineInstruction =
+ (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op1Def : Op2Def;
MachineOperand &ConstantOperand = constantMachineInstruction->getOperand(1);
if (!ConstantOperand.isFPImm())
@@ -406,9 +408,7 @@ bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
const APFloat &Val = Constant->getValueAPF();
APFloat Expected(180.0 / std::acos(-1.0));
bool LostInfo = false;
- Expected.convert(Val.getSemantics(),
- APFloat::rmNearestTiesToEven,
- &LostInfo);
+ Expected.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &LostInfo);
if (Expected.compare(Val) != APFloat::cmpEqual)
return false;
@@ -422,7 +422,8 @@ void SPIRVCombinerHelper::applyDegrees(MachineInstr &MI) const {
Register Op2 = MI.getOperand(2).getReg();
MachineInstr *Op1Def = MRI.getVRegDef(Op1);
MachineInstr *Op2Def = MRI.getVRegDef(Op2);
- Register nonConstantReg = (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op2 : Op1;
+ Register nonConstantReg =
+ (Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op2 : Op1;
Builder.setInstrAndDebugLoc(MI);
Builder.buildIntrinsic(Intrinsic::spv_degrees, ResultReg)
>From e2b3a3627501859a3eafc93aedc60bae8a0d9b7f Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sun, 16 Aug 2026 01:21:51 +0530
Subject: [PATCH 3/5] clang format
---
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 0da5ab6337ebb..49bd2bb1f0901 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -393,11 +393,11 @@ bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
if (!Op1Def || !Op2Def)
return false;
- if (Op1Def->getOpcode() != TargetOpcode::G_FCONSTANT &&
+ if (Op1Def->getOpcode() != TargetOpcode::G_FCONSTANT &&
Op2Def->getOpcode() != TargetOpcode::G_FCONSTANT)
return false;
- MachineInstr *constantMachineInstruction =
+ MachineInstr *constantMachineInstruction =
(Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op1Def : Op2Def;
MachineOperand &ConstantOperand = constantMachineInstruction->getOperand(1);
@@ -422,9 +422,9 @@ void SPIRVCombinerHelper::applyDegrees(MachineInstr &MI) const {
Register Op2 = MI.getOperand(2).getReg();
MachineInstr *Op1Def = MRI.getVRegDef(Op1);
MachineInstr *Op2Def = MRI.getVRegDef(Op2);
- Register nonConstantReg =
+ Register nonConstantReg =
(Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op2 : Op1;
-
+
Builder.setInstrAndDebugLoc(MI);
Builder.buildIntrinsic(Intrinsic::spv_degrees, ResultReg)
.addUse(nonConstantReg);
>From 711e56136b3cc45cd2ce207d6aa45184ab6ed576 Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sun, 16 Aug 2026 09:49:51 +0530
Subject: [PATCH 4/5] using llvm pi instead of acos
---
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 49bd2bb1f0901..4a03a87c312ac 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -406,7 +406,8 @@ bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
const ConstantFP *Constant = ConstantOperand.getFPImm();
const APFloat &Val = Constant->getValueAPF();
- APFloat Expected(180.0 / std::acos(-1.0));
+
+ APFloat Expected(180.0 / llvm::numbers::pi);
bool LostInfo = false;
Expected.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &LostInfo);
>From 5c8a18eb6afd81658781e5bb9863879b968f8f2d Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sun, 16 Aug 2026 23:23:58 +0530
Subject: [PATCH 5/5] removed unused variable
---
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 4a03a87c312ac..f15a3aa63f8ad 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -422,7 +422,6 @@ void SPIRVCombinerHelper::applyDegrees(MachineInstr &MI) const {
Register Op1 = MI.getOperand(1).getReg();
Register Op2 = MI.getOperand(2).getReg();
MachineInstr *Op1Def = MRI.getVRegDef(Op1);
- MachineInstr *Op2Def = MRI.getVRegDef(Op2);
Register nonConstantReg =
(Op1Def->getOpcode() == TargetOpcode::G_FCONSTANT) ? Op2 : Op1;
More information about the llvm-commits
mailing list