[llvm] Add PreLegalizer pattern matching for degrees GL extension (PR #216506)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 22 08:09:14 PDT 2026
https://github.com/albertbolt1 updated https://github.com/llvm/llvm-project/pull/216506
>From bc2c8f057db19e353d10915fc7f16f9e9a77f95f 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/6] 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 e6c4e69673b97..a9f1dab6269e6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombine.td
+++ b/llvm/lib/Target/SPIRV/SPIRVCombine.td
@@ -38,10 +38,16 @@ def matrix_multiply_lowering
m_GIntrinsic<Intrinsic::matrix_multiply>()); }]),
(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 d6166e5c4e46a..dc31bb4318f0f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -363,3 +363,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 26deb9d146653..4e46618704146 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
@@ -35,6 +35,8 @@ class SPIRVCombinerHelper : public CombinerHelper {
void applySPIRVFaceForward(MachineInstr &MI) const;
void applyMatrixTranspose(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 117ead02b19e1b2eaea4e15da6be6637486ae48c 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/6] 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 dc31bb4318f0f..77f291d03dd7b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -375,10 +375,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())
@@ -388,9 +390,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;
@@ -404,7 +404,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 4cab79c57c1f81acfe347fd2bf182c2c8dc69d5c 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/6] 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 77f291d03dd7b..ee2d2350fa430 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -375,11 +375,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);
@@ -404,9 +404,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 b4a254f72e175caf1d185a874a99f4865ac2d1c6 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/6] 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 ee2d2350fa430..df03e4fe265b8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -388,7 +388,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 2b06cc655aaf45dee761bfb227cd2fe518623572 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/6] 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 df03e4fe265b8..dcc19349d5cb2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -404,7 +404,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;
>From baa2c53c620424cdd3379b89363a0814330c2561 Mon Sep 17 00:00:00 2001
From: albertbolt <albertboltinfinity at gmail.com>
Date: Sat, 22 Aug 2026 20:36:55 +0530
Subject: [PATCH 6/6] review comments handled
---
llvm/lib/Target/SPIRV/SPIRVCombine.td | 12 +-
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 109 ++++++++++--------
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h | 5 +-
.../prelegalizercombiner-fmul-to-degrees.mir | 54 +++++++++
.../CodeGen/SPIRV/hlsl-intrinsics/degrees.ll | 18 +++
.../hlsl-intrinsics/degrees_nointrinsic.ll | 14 ---
llvm/test/CodeGen/SPIRV/opencl/degrees.ll | 18 +++
7 files changed, 158 insertions(+), 72 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-fmul-to-degrees.mir
delete 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 a9f1dab6269e6..b2fb477b73c2e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombine.td
+++ b/llvm/lib/Target/SPIRV/SPIRVCombine.td
@@ -22,6 +22,12 @@ def vector_select_to_faceforward_lowering : GICombineRule <
(apply [{ Helper.applySPIRVFaceForward(*${root}); }])
>;
+def degrees_lowering
+ : GICombineRule<(defs root:$root),
+ (match (wip_match_opcode G_FMUL):$root,
+ [{ return Helper.matchDegrees(*${root}); }]),
+ (apply [{ Helper.applyDegrees(*${root}); }])>;
+
def matrix_transpose_lowering
: GICombineRule<
(defs root:$root),
@@ -38,12 +44,6 @@ def matrix_multiply_lowering
m_GIntrinsic<Intrinsic::matrix_multiply>()); }]),
(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,
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index dcc19349d5cb2..79a6b7473308e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -185,6 +185,65 @@ void SPIRVCombinerHelper::applySPIRVFaceForward(MachineInstr &MI) const {
MI.eraseFromParent();
}
+/// This match is part of a combine that
+/// rewrites fmul (x,180/pi) to degrees(x)
+/// (f32 (g_fmul
+/// (f32 X)
+/// (f32 180/pi)))
+/// ->
+/// (f32 (g_intrinsic degrees
+/// (f32 X)))
+///
+/// The constant operand may also be a splat for vector types:
+/// (vXf32 (g_fmul
+/// (vXf32 X)
+/// (vXf32 splat(180/pi))))
+/// ->
+/// (vXf32 (g_intrinsic degrees
+/// (vXf32 X)))
+bool SPIRVCombinerHelper::matchDegrees(MachineInstr &MI) const {
+ Register NonConstReg;
+ std::optional<FPValueAndVReg> ConstVal;
+
+ if (!mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GFMul(m_Reg(NonConstReg), m_GFCstOrSplat(ConstVal))) &&
+ !mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GFMul(m_GFCstOrSplat(ConstVal), m_Reg(NonConstReg))))
+ return false;
+
+ if (!ConstVal)
+ return false;
+
+ APFloat Expected(180.0 / llvm::numbers::pi);
+ bool LostInfo = false;
+ Expected.convert(ConstVal->Value.getSemantics(), APFloat::rmNearestTiesToEven,
+ &LostInfo);
+ return Expected.compare(ConstVal->Value) == APFloat::cmpEqual;
+}
+
+void SPIRVCombinerHelper::applyDegrees(MachineInstr &MI) const {
+ Register ResultReg = MI.getOperand(0).getReg();
+ Register NonConstReg;
+ std::optional<FPValueAndVReg> ConstVal;
+
+ if (!mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GFMul(m_Reg(NonConstReg), m_GFCstOrSplat(ConstVal))) &&
+ !mi_match(MI.getOperand(0).getReg(), MRI,
+ m_GFMul(m_GFCstOrSplat(ConstVal), m_Reg(NonConstReg)))) {
+ return;
+ }
+
+ Builder.setInstrAndDebugLoc(MI);
+ Builder.buildIntrinsic(Intrinsic::spv_degrees, ResultReg).addUse(NonConstReg);
+
+ MI.eraseFromParent();
+}
+
+bool SPIRVCombinerHelper::matchMatrixTranspose(MachineInstr &MI) const {
+ return MI.getOpcode() == TargetOpcode::G_INTRINSIC &&
+ cast<GIntrinsic>(MI).getIntrinsicID() == Intrinsic::matrix_transpose;
+}
+
void SPIRVCombinerHelper::applyMatrixTranspose(MachineInstr &MI) const {
Register ResReg = MI.getOperand(0).getReg();
Register InReg = MI.getOperand(2).getReg();
@@ -362,54 +421,4 @@ void SPIRVCombinerHelper::applyMatrixMultiply(MachineInstr &MI) const {
else
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 / llvm::numbers::pi);
- 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);
- 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 4e46618704146..de727d5154414 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.h
@@ -33,10 +33,11 @@ class SPIRVCombinerHelper : public CombinerHelper {
void applySPIRVDistance(MachineInstr &MI) const;
bool matchSelectToFaceForward(MachineInstr &MI) const;
void applySPIRVFaceForward(MachineInstr &MI) const;
- void applyMatrixTranspose(MachineInstr &MI) const;
- void applyMatrixMultiply(MachineInstr &MI) const;
bool matchDegrees(MachineInstr &MI) const;
void applyDegrees(MachineInstr &MI) const;
+ bool matchMatrixTranspose(MachineInstr &MI) const;
+ void applyMatrixTranspose(MachineInstr &MI) const;
+ void applyMatrixMultiply(MachineInstr &MI) const;
private:
SPIRVTypeInst getDotProductVectorType(Register ResReg, uint32_t K,
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-fmul-to-degrees.mir b/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-fmul-to-degrees.mir
new file mode 100644
index 0000000000000..d2399379f97a2
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-fmul-to-degrees.mir
@@ -0,0 +1,54 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -verify-machineinstrs -O0 -mtriple spirv-unknown-unknown -run-pass=spirv-prelegalizer-combiner %s -o - | FileCheck %s
+---
+name: degrees_instcombine_float
+tracksRegLiveness: true
+legalized: true
+body: |
+ bb.1.entry:
+ ; CHECK-LABEL: name: degrees_instcombine_float
+ ; CHECK: [[OpTypeFloat:%[0-9]+]]:type(s64) = OpTypeFloat 32
+ ; CHECK-NEXT: [[OpTypeFunction:%[0-9]+]]:type(s64) = OpTypeFunction [[OpTypeFloat]](s64), [[OpTypeFloat]](s64)
+ ; CHECK-NEXT: OpName %2(s32), 120
+ ; CHECK-NEXT: [[OpFunction:%[0-9]+]]:iid(s64) = OpFunction [[OpTypeFloat]](s64), 5, [[OpTypeFunction]](s64)
+ ; CHECK-NEXT: [[OpFunctionParameter:%[0-9]+]]:fid(s32) = OpFunctionParameter [[OpTypeFloat]](s64)
+ ; CHECK-NEXT: OpName [[OpFunction]](s64), 1949588063, 1718907749, 0
+ ; CHECK-NEXT: [[INT:%[0-9]+]]:id(s32) = G_INTRINSIC intrinsic(@llvm.spv.degrees), [[OpFunctionParameter]](s32)
+ ; CHECK-NEXT: OpReturnValue [[INT]](s32)
+ %1:type(s64) = OpTypeFloat 32
+ %3:type(s64) = OpTypeFunction %1(s64), %1(s64)
+ OpName %0(s32), 120
+ %2:iid(s64) = OpFunction %1(s64), 5, %3(s64)
+ %0:fid(s32) = OpFunctionParameter %1(s64)
+ OpName %2(s64), 1949588063, 1718907749, 0
+ %4:_(s32) = G_FCONSTANT float f0x42652EE1
+ %5:id(s32) = nnan ninf nsz arcp afn reassoc G_FMUL %0, %4
+ OpReturnValue %5(s32)
+...
+---
+name: degrees_instcombine_float4
+tracksRegLiveness: true
+legalized: true
+body: |
+ bb.1.entry:
+ ; CHECK-LABEL: name: degrees_instcombine_float4
+ ; CHECK: [[OpTypeVector:%[0-9]+]]:type(s64) = OpTypeVector %1(s64), 4
+ ; CHECK-NEXT: [[OpTypeFunction:%[0-9]+]]:type(s64) = OpTypeFunction [[OpTypeVector]](s64), [[OpTypeVector]](s64)
+ ; CHECK-NEXT: [[OpTypeFloat:%[0-9]+]]:type(s64) = OpTypeFloat 32
+ ; CHECK-NEXT: OpName %3(<4 x s32>), 118
+ ; CHECK-NEXT: [[OpFunction:%[0-9]+]]:iid(s64) = OpFunction [[OpTypeVector]](s64), 5, [[OpTypeFunction]](s64)
+ ; CHECK-NEXT: [[OpFunctionParameter:%[0-9]+]]:vfid(<4 x s32>) = OpFunctionParameter [[OpTypeVector]](s64)
+ ; CHECK-NEXT: OpName [[OpFunction]](s64), 808540767, 1953719668, 1952671062, 1984197231, 6709044
+ ; CHECK-NEXT: [[INT:%[0-9]+]]:id(<4 x s32>) = G_INTRINSIC intrinsic(@llvm.spv.degrees), [[OpFunctionParameter]](<4 x s32>)
+ ; CHECK-NEXT: OpReturnValue [[INT]](<4 x s32>)
+ %2:type(s64) = OpTypeVector %1(s64), 4
+ %4:type(s64) = OpTypeFunction %2(s64), %2(s64)
+ %1:type(s64) = OpTypeFloat 32
+ OpName %0(<4 x s32>), 118
+ %3:iid(s64) = OpFunction %2(s64), 5, %4(s64)
+ %0:vfid(<4 x s32>) = OpFunctionParameter %2(s64)
+ OpName %3(s64), 808540767, 1953719668, 1952671062, 1984197231, 6709044
+ %6:_(s32) = G_FCONSTANT float f0x42652EE1
+ %5:_(<4 x s32>) = G_BUILD_VECTOR %6(s32), %6(s32), %6(s32), %6(s32)
+ %7:id(<4 x s32>) = nnan ninf nsz arcp afn reassoc G_FMUL %0, %5
+ OpReturnValue %7(<4 x s32>)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll
index d2d929b152cda..74fabad8b1b80 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll
@@ -45,6 +45,24 @@ entry:
ret <4 x half> %elt.degrees
}
+; CHECK-LABEL: Begin function fmul_to_degrees
+define noundef float @fmul_to_degrees(float noundef %x) {
+entry:
+; CHECK: %[[#arg:]] = OpFunctionParameter %[[#float_32]]
+; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Degrees %[[#arg]]
+ %mul = fmul reassoc nnan ninf nsz arcp afn float %x, f0x42652EE1
+ ret float %mul
+}
+
+; CHECK-LABEL: Begin function fmul_to_degrees_vector
+define hidden noundef nofpclass(nan inf) <4 x float> @fmul_to_degrees_vector(<4 x float> noundef nofpclass(nan inf) %v) local_unnamed_addr #0 {
+entry:
+; CHECK: %[[#arg:]] = OpFunctionParameter %[[#vec4_float_32]]
+; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Degrees %[[#arg]]
+ %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %v, splat (float f0x42652EE1)
+ ret <4 x float> %mul.i
+}
+
declare half @llvm.spv.degrees.f16(half)
declare float @llvm.spv.degrees.f32(float)
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll
deleted file mode 100644
index 4554559ca6b14..0000000000000
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees_nointrinsic.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; 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
diff --git a/llvm/test/CodeGen/SPIRV/opencl/degrees.ll b/llvm/test/CodeGen/SPIRV/opencl/degrees.ll
index b8d4f52a28795..ed008c1cd348c 100644
--- a/llvm/test/CodeGen/SPIRV/opencl/degrees.ll
+++ b/llvm/test/CodeGen/SPIRV/opencl/degrees.ll
@@ -48,3 +48,21 @@ entry:
%elt.degrees = call <4 x half> @llvm.spv.degrees.v4f16(<4 x half> %a)
ret <4 x half> %elt.degrees
}
+
+; CHECK-LABEL: Begin function fmul_to_degrees
+define noundef float @fmul_to_degrees(float noundef %x) {
+entry:
+; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
+; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_ocl]] degrees %[[#float_32_arg]]
+ %mul = fmul reassoc nnan ninf nsz arcp afn float %x, f0x42652EE1
+ ret float %mul
+}
+
+; CHECK-LABEL: Begin function fmul_to_degrees_vector
+define hidden noundef nofpclass(nan inf) <4 x float> @fmul_to_degrees_vector(<4 x float> noundef nofpclass(nan inf) %v) local_unnamed_addr #0 {
+entry:
+; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
+; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_ocl]] degrees %[[#vec4_float_32_arg]]
+ %mul.i = fmul reassoc nnan ninf nsz arcp afn <4 x float> %v, splat (float f0x42652EE1)
+ ret <4 x float> %mul.i
+}
\ No newline at end of file
More information about the llvm-commits
mailing list