[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