[llvm] [HLSL] Move FNeg legalization to the DXILLegalization pass (PR #140942)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 21 10:56:52 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-directx

Author: Sumit Agarwal (sumitsays)

<details>
<summary>Changes</summary>

This solves #<!-- -->137685 

---
Full diff: https://github.com/llvm/llvm-project/pull/140942.diff


4 Files Affected:

- (modified) llvm/lib/Target/DirectX/DXILLegalizePass.cpp (+15) 
- (modified) llvm/lib/Target/DirectX/DXILPrepare.cpp (-9) 
- (removed) llvm/test/CodeGen/DirectX/fneg-conversion.ll (-16) 
- (added) llvm/test/CodeGen/DirectX/legalize-fneg.ll (+23) 


``````````diff
diff --git a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
index 7f8903a9d5925..511e9835f56a7 100644
--- a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
+++ b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
@@ -405,6 +405,20 @@ static void removeMemSet(Instruction &I,
   ToRemove.push_back(CI);
 }
 
+static void updateFnegToFsub(Instruction &I,
+                             SmallVectorImpl<Instruction *> &ToRemove,
+                             DenseMap<Value *, Value *> &ReplacedValues) {
+  const Intrinsic::ID ID = I.getOpcode();
+  if(ID != Instruction::FNeg)
+    return;
+
+  IRBuilder<> Builder(&I);
+  Value *In = I.getOperand(0);
+  Value *Zero = ConstantFP::get(In->getType(), -0.0);
+  I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
+  ToRemove.push_back(&I);
+}
+
 namespace {
 class DXILLegalizationPipeline {
 
@@ -438,6 +452,7 @@ class DXILLegalizationPipeline {
     LegalizationPipeline.push_back(legalizeFreeze);
     LegalizationPipeline.push_back(legalizeMemCpy);
     LegalizationPipeline.push_back(removeMemSet);
+    LegalizationPipeline.push_back(updateFnegToFsub);
   }
 };
 
diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index e9a05a7b90aca..e0068787f5e5a 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -204,15 +204,6 @@ class DXILPrepareModule : public ModulePass {
 
           I.dropUnknownNonDebugMetadata(DXILCompatibleMDs);
 
-          if (I.getOpcode() == Instruction::FNeg) {
-            Builder.SetInsertPoint(&I);
-            Value *In = I.getOperand(0);
-            Value *Zero = ConstantFP::get(In->getType(), -0.0);
-            I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
-            I.eraseFromParent();
-            continue;
-          }
-
           // Emtting NoOp bitcast instructions allows the ValueEnumerator to be
           // unmodified as it reserves instruction IDs during contruction.
           if (auto LI = dyn_cast<LoadInst>(&I)) {
diff --git a/llvm/test/CodeGen/DirectX/fneg-conversion.ll b/llvm/test/CodeGen/DirectX/fneg-conversion.ll
deleted file mode 100644
index 3acf4790de4b1..0000000000000
--- a/llvm/test/CodeGen/DirectX/fneg-conversion.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: llc %s --filetype=asm -o - | FileCheck %s
-target triple = "dxil-unknown-shadermodel6.7-library"
-
-define float @negateF(float %0) #0 {
-; CHECK:  %2 = fsub float -0.000000e+00, %0
-  %2 = fneg float %0
-  ret float %2
-}
-
-define double @negateD(double %0) #0 {
-; CHECK: %2 = fsub double -0.000000e+00, %0
-  %2 = fneg double %0
-  ret double %2
-}
-
-attributes #0 = { convergent norecurse nounwind "hlsl.export"}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/DirectX/legalize-fneg.ll b/llvm/test/CodeGen/DirectX/legalize-fneg.ll
new file mode 100644
index 0000000000000..996cbbfc59e0f
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/legalize-fneg.ll
@@ -0,0 +1,23 @@
+; RUN: opt -S -passes='dxil-legalize' -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
+
+define float @negateF(float %x) {
+; CHECK-LABEL: define float @negateF(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[Y:%.*]] = fsub float -0.000000e+00, [[X]]
+; CHECK-NEXT:    ret float [[Y]]
+entry:  
+  %y = fneg float %x
+  ret float %y
+}
+
+define double @negateD(double %x) {
+; CHECK-LABEL: define double @negateD(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[Y:%.*]] = fsub double -0.000000e+00, [[X]]
+; CHECK-NEXT:    ret double [[Y]]
+entry:  
+  %y = fneg double %x
+  ret double %y
+}
\ No newline at end of file

``````````

</details>


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


More information about the llvm-commits mailing list