[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