[clang] [llvm] [SPIRV] Add PreLegalizer pattern matching for `faceforward` (PR #139959)

Farzon Lotfi via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 17 08:41:17 PDT 2025


================
@@ -58,3 +58,106 @@ void SPIRVCombinerHelper::applySPIRVDistance(MachineInstr &MI) const {
 
   MI.eraseFromParent();
 }
+
+/// This match is part of a combine that
+/// rewrites select(fcmp(dot(I, Ng), 0), N, -N) to faceforward(N, I, Ng)
+///   (vXf32 (g_select
+///             (g_fcmp
+///                (g_intrinsic dot(vXf32 I) (vXf32 Ng)
+///                 0)
+///             (vXf32 N)
+///             (vXf32 g_fneg (vXf32 N))))
+/// ->
+///   (vXf32 (g_intrinsic faceforward
+///             (vXf32 N) (vXf32 I) (vXf32 Ng)))
+///
+/// This only works for Vulkan targets.
+///
+bool SPIRVCombinerHelper::matchSelectToFaceForward(MachineInstr &MI) const {
+  if (!STI.isShader())
+    return false;
+
+  // Match overall select pattern.
+  Register CondReg, TrueReg, FalseReg;
+  if (!mi_match(MI.getOperand(0).getReg(), MRI,
+                m_GISelect(m_Reg(CondReg), m_Reg(TrueReg), m_Reg(FalseReg))))
+    return false;
+
+  // Match the FCMP condition.
+  Register DotReg, CondZeroReg;
+  CmpInst::Predicate Pred;
+  if (!mi_match(CondReg, MRI,
+                m_GFCmp(m_Pred(Pred), m_Reg(DotReg), m_Reg(CondZeroReg))) ||
+      Pred != CmpInst::FCMP_OLT)
----------------
farzonl wrote:

my concern is what if an optimization pass comes along and rewrites our faceforward implementation and the condition changes for the comparison. How robust are we to handling something like this?

https://github.com/llvm/llvm-project/pull/139959


More information about the cfe-commits mailing list