[llvm] caf83f9 - [SPIR-V] Fix FaceForward combine erasing unrelated users (#214626)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 8 11:37:18 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-08-08T20:37:13+02:00
New Revision: caf83f904bf468bc534b4ecf7f0fc4bc77713ff1

URL: https://github.com/llvm/llvm-project/commit/caf83f904bf468bc534b4ecf7f0fc4bc77713ff1
DIFF: https://github.com/llvm/llvm-project/commit/caf83f904bf468bc534b4ecf7f0fc4bc77713ff1.diff

LOG: [SPIR-V] Fix FaceForward combine erasing unrelated users (#214626)

Only erase the matched select and let normal DCE remove producers that
actually become dead

Added: 
    

Modified: 
    llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
    llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir
    llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index 660bee0f7a2cd..0882970895452 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -182,7 +182,6 @@ void SPIRVCombinerHelper::applySPIRVFaceForward(MachineInstr &MI) const {
   if (TrueInstr->getOpcode() == TargetOpcode::G_FNEG ||
       TrueInstr->getOpcode() == TargetOpcode::G_FMUL)
     std::swap(TrueReg, FalseReg);
-  MachineInstr *FalseInstr = MRI.getVRegDef(FalseReg);
 
   Register ResultReg = MI.getOperand(0).getReg();
   Builder.setInstrAndDebugLoc(MI);
@@ -191,27 +190,7 @@ void SPIRVCombinerHelper::applySPIRVFaceForward(MachineInstr &MI) const {
       .addUse(DotOperand1)  // I
       .addUse(DotOperand2); // Ng
 
-  SPIRVGlobalRegistry *GR =
-      MI.getMF()->getSubtarget<SPIRVSubtarget>().getSPIRVGlobalRegistry();
-  auto RemoveAllUses = [&](Register Reg) {
-    SmallVector<MachineInstr *, 4> UsesToErase;
-    for (auto &UseMI : MRI.use_instructions(Reg))
-      UsesToErase.push_back(&UseMI);
-
-    // calling eraseFromParent to early invalidates the iterator.
-    for (auto *MIToErase : UsesToErase)
-      MIToErase->eraseFromParent();
-  };
-
-  RemoveAllUses(CondReg); // remove all uses of FCMP Result
-  GR->invalidateMachineInstr(CondInstr);
-  CondInstr->eraseFromParent(); // remove FCMP instruction
-  RemoveAllUses(DotReg);        // remove all uses of spv_fdot/G_FMUL Result
-  GR->invalidateMachineInstr(DotInstr);
-  DotInstr->eraseFromParent(); // remove spv_fdot/G_FMUL instruction
-  RemoveAllUses(FalseReg);
-  GR->invalidateMachineInstr(FalseInstr);
-  FalseInstr->eraseFromParent();
+  MI.eraseFromParent();
 }
 
 bool SPIRVCombinerHelper::matchMatrixTranspose(MachineInstr &MI) const {

diff  --git a/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir b/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir
index 7ca8e1439610b..0d160319b1dba 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/InstCombine/prelegalizercombiner-select-to-faceforward.mir
@@ -195,4 +195,70 @@ body:             |
     %12:_(<4 x s32>) = G_FNEG %0:vfid
     %13:id(<4 x s32>) = G_SELECT %11:_(s1), %12:_, %0:vfid
     OpReturnValue %13:id(<4 x s32>)
-
+---
+name:            faceforward_instcombine_float_shared_condition
+tracksRegLiveness: true
+legalized: true
+body:             |
+  bb.1.entry:
+    ; CHECK-LABEL: name: faceforward_instcombine_float_shared_condition
+    ; CHECK: %7:_(s32) = G_FMUL %3, %4
+    ; CHECK: %8:_(s1) = G_FCMP floatpred(olt), %7(s32), %6
+    ; CHECK: %10:id(s32) = G_INTRINSIC intrinsic(@llvm.spv.faceforward), %2(s32), %3(s32), %4(s32)
+    ; CHECK: %11:id(s32) = G_SELECT %8(s1), %3, %4
+    ; CHECK: %12:id(s32) = G_FADD %10, %11
+    ; CHECK: OpReturnValue %12(s32)
+    %3:type(s64) = OpTypeFloat 32
+    %5:type(s64) = OpTypeFunction %3:type(s64), %3:type(s64), %3:type(s64), %3:type(s64)
+    OpName %0:fid(s32), 97
+    OpName %1:fid(s32), 98
+    OpName %2:fid(s32), 99
+    %4:iid(s64) = OpFunction %3:type(s64), 0, %5:type(s64)
+    %0:fid(s32) = OpFunctionParameter %3:type(s64)
+    %1:fid(s32) = OpFunctionParameter %3:type(s64)
+    %2:fid(s32) = OpFunctionParameter %3:type(s64)
+    OpName %4:iid(s64), 1701011814, 2003988326, 1600418401, 1953721961, 1651339107, 1600482921, 1634692198, 1752391540, 1684370017, 1852793695, 1769236836, 28271
+    %9:_(s32) = G_FCONSTANT float 0.000000e+00
+    %8:_(s32) = G_FMUL %1:fid, %2:fid
+    %10:_(s1) = G_FCMP floatpred(olt), %8:_(s32), %9:_
+    %11:_(s32) = G_FNEG %0:fid
+    %12:id(s32) = G_SELECT %10:_(s1), %0:fid, %11:_
+    %13:id(s32) = G_SELECT %10:_(s1), %1:fid, %2:fid
+    %14:id(s32) = G_FADD %12:id, %13:id
+    OpReturnValue %14:id(s32)
+...
+---
+name:            faceforward_instcombine_float4_shared_dot
+tracksRegLiveness: true
+legalized: true
+body:             |
+  bb.1.entry:
+    ; CHECK-LABEL: name: faceforward_instcombine_float4_shared_dot
+    ; CHECK: %8:_(s32) = G_INTRINSIC intrinsic(@llvm.spv.fdot), %4(<4 x s32>), %5(<4 x s32>)
+    ; CHECK: %11:id(<4 x s32>) = G_INTRINSIC intrinsic(@llvm.spv.faceforward), %3(<4 x s32>), %4(<4 x s32>), %5(<4 x s32>)
+    ; CHECK: %13:_(s1) = G_FCMP floatpred(ogt), %8(s32), %12
+    ; CHECK: %14:id(<4 x s32>) = G_SELECT %13(s1), %4, %5
+    ; CHECK: %15:id(<4 x s32>) = G_FADD %11, %14
+    ; CHECK: OpReturnValue %15(<4 x s32>)
+    %4:type(s64) = OpTypeVector %3:type(s64), 4
+    %6:type(s64) = OpTypeFunction %4:type(s64), %4:type(s64), %4:type(s64), %4:type(s64)
+    %3:type(s64) = OpTypeFloat 32
+    OpName %0:vfid(<4 x s32>), 97
+    OpName %1:vfid(<4 x s32>), 98
+    OpName %2:vfid(<4 x s32>), 99
+    %5:iid(s64) = OpFunction %4:type(s64), 0, %6:type(s64)
+    %0:vfid(<4 x s32>) = OpFunctionParameter %4:type(s64)
+    %1:vfid(<4 x s32>) = OpFunctionParameter %4:type(s64)
+    %2:vfid(<4 x s32>) = OpFunctionParameter %4:type(s64)
+    OpName %5:iid(s64), 1701011814, 2003988326, 1600418401, 1953721961, 1651339107, 1600482921, 1634692198, 1935619188, 1701994856, 1868848996, 116
+    %10:_(s32) = G_FCONSTANT float 0.000000e+00
+    %9:_(s32) = G_INTRINSIC intrinsic(@llvm.spv.fdot), %1:vfid(<4 x s32>), %2:vfid(<4 x s32>)
+    %11:_(s1) = G_FCMP floatpred(olt), %9:_(s32), %10:_
+    %13:_(<4 x s32>) = G_FNEG %0:vfid
+    %14:id(<4 x s32>) = G_SELECT %11:_(s1), %0:vfid, %13:_
+    %12:_(s32) = G_FCONSTANT float 5.000000e+00
+    %17:_(s1) = G_FCMP floatpred(ogt), %9:_(s32), %12:_
+    %15:id(<4 x s32>) = G_SELECT %17:_(s1), %1:vfid, %2:vfid
+    %16:id(<4 x s32>) = G_FADD %14:id, %15:id
+    OpReturnValue %16:id(<4 x s32>)
+...

diff  --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
index f7aa42a53de8a..1a6231e3a39c6 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll
@@ -148,6 +148,24 @@ entry:
   ret <4 x float> %select
 }
 
+define internal float @faceforward_instcombine_float_shared_dot_store(float %a, float %b, float %c, ptr %out) {
+entry:
+  ; CHECK: %[[#]] = OpFunction %[[#float_32]] None %[[#]]
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#float_32]]
+  ; CHECK: %[[#arg3:]] = OpFunctionParameter %[[#]]
+  ; CHECK: %[[#dot:]] = OpFMul %[[#float_32]] %[[#arg1]] %[[#arg2]]
+  ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FaceForward %[[#arg0]] %[[#arg1]] %[[#arg2]]
+  ; CHECK: OpStore %[[#arg3]] %[[#dot]]
+  %fmul = fmul float %b, %c
+  %fcmp = fcmp olt float %fmul, 0.000000e+00
+  %fneg = fneg float %a
+  %select = select i1 %fcmp, float %a, float %fneg
+  store float %fmul, ptr %out, align 4
+  ret float %select
+}
+
 ; The other functions are the test, but a entry point is required to have a valid SPIR-V module.
 define void @main() #1 {
 entry:


        


More information about the llvm-commits mailing list