[llvm] Adjust bit cast instruction filter for DXIL Prepare pass (PR #142678)

Joshua Batista via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 3 16:25:35 PDT 2025


https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/142678

>From 0aff10620880dd7f58bd453ef5836fbf963f35dd Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 3 Jun 2025 15:03:02 -0700
Subject: [PATCH 1/2] first attempt

---
 llvm/lib/Target/DirectX/DXILPrepare.cpp       | 37 +++++++++++++++++-
 .../DirectX/noop_bitcast_global_array_type.ll | 39 +++++++++++++++++++
 2 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/DirectX/noop_bitcast_global_array_type.ll

diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index e0068787f5e5a..54e4499830ff0 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -148,9 +148,42 @@ class DXILPrepareModule : public ModulePass {
                                      Type *Ty) {
     // Omit bitcasts if the incoming value matches the instruction type.
     auto It = PointerTypes.find(Operand);
-    if (It != PointerTypes.end())
-      if (cast<TypedPointerType>(It->second)->getElementType() == Ty)
+    if (It != PointerTypes.end()) {
+      auto OpTy = cast<TypedPointerType>(It->second)->getElementType();
+      if (OpTy == Ty)
         return nullptr;
+    }
+
+    // Also omit the bitcast for matching global array types
+    if (auto *GlobalVar = llvm::dyn_cast<llvm::GlobalVariable>(Operand)) {
+      llvm::Type *ValTy = GlobalVar->getValueType();
+
+      if (auto *ArrTy = llvm::dyn_cast<llvm::ArrayType>(ValTy)) {
+        llvm::Type *ElTy = ArrTy->getElementType();
+        if (ElTy == Ty)
+          return nullptr;
+      }
+    }
+
+    // finally, drill down GEP instructions until we get the array
+    // that is being accessed, and compare element types
+    if (auto *GEPInstr = llvm::dyn_cast<llvm::ConstantExpr>(Operand)) {
+      while (GEPInstr->getOpcode() == llvm::Instruction::GetElementPtr) {
+        llvm::Value *OpArg = GEPInstr->getOperand(0);
+
+        if (auto *GlobalVar = llvm::dyn_cast<llvm::GlobalVariable>(OpArg)) {
+          llvm::Constant *initializer = GlobalVar->getInitializer();
+
+          llvm::Type *ValTy = GlobalVar->getValueType();
+          if (auto *ArrTy = llvm::dyn_cast<llvm::ArrayType>(ValTy)) {
+            llvm::Type *ElTy = ArrTy->getElementType();
+            if (ElTy == Ty)
+              return nullptr;
+          }
+        }
+      }
+    }
+
     // Insert bitcasts where we are removing the instruction.
     Builder.SetInsertPoint(&Inst);
     // This code only gets hit in opaque-pointer mode, so the type of the
diff --git a/llvm/test/CodeGen/DirectX/noop_bitcast_global_array_type.ll b/llvm/test/CodeGen/DirectX/noop_bitcast_global_array_type.ll
new file mode 100644
index 0000000000000..4cca76efcf461
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/noop_bitcast_global_array_type.ll
@@ -0,0 +1,39 @@
+; RUN: opt -S --dxil-prepare %s | FileCheck %s
+
+; Test that global arrays do not get a bitcast instruction
+; after the dxil-prepare pass.
+
+target triple = "dxilv1.2-unknown-shadermodel6.2-compute"
+
+ at inputTile.1dim = local_unnamed_addr addrspace(3) global [3 x float] zeroinitializer, align 2
+
+define float @testload() local_unnamed_addr {
+  ; NOTE: this would be "bitcast ptr addrspace(3)..." before the change that introduced this test,
+  ; after the dxil-prepare pass is run
+  ; CHECK: load float, ptr addrspace(3) @inputTile.1dim, align 2
+  %v = load float, ptr addrspace(3) @inputTile.1dim, align 2  
+  
+  ret float %v
+}
+
+define void @teststore() local_unnamed_addr {  
+  ; CHECK: store float 2.000000e+00, ptr addrspace(3) @inputTile.1dim, align 2
+  store float 2.000000e+00, ptr addrspace(3) @inputTile.1dim, align 2  
+  
+  ret void
+}
+
+define float @testGEPConst() local_unnamed_addr {  
+  ; CHECK: load float, ptr addrspace(3) getelementptr (float, ptr addrspace(3) @inputTile.1dim, i32 1), align 4
+  %v = load float, ptr addrspace(3) getelementptr (float, ptr addrspace(3) @inputTile.1dim, i32 1), align 4
+  
+  ret float %v
+}
+
+define float @testGEPNonConst(i32 %i) local_unnamed_addr {  
+  ; CHECK: getelementptr float, ptr addrspace(3) @inputTile.1dim, i32 %i
+  %gep = getelementptr float, ptr addrspace(3) @inputTile.1dim, i32 %i
+  %v = load float, ptr addrspace(3) %gep
+  
+  ret float %v
+}

>From 9c6cad47e2c21d79a118c2e949ac29da032f9404 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 3 Jun 2025 16:24:48 -0700
Subject: [PATCH 2/2] fix while loop

---
 llvm/lib/Target/DirectX/DXILPrepare.cpp | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 54e4499830ff0..8bd5e40100de0 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -167,13 +167,17 @@ class DXILPrepareModule : public ModulePass {
 
     // finally, drill down GEP instructions until we get the array
     // that is being accessed, and compare element types
-    if (auto *GEPInstr = llvm::dyn_cast<llvm::ConstantExpr>(Operand)) {
+    if (llvm::ConstantExpr *GEPInstr =
+            llvm::dyn_cast<llvm::ConstantExpr>(Operand)) {
       while (GEPInstr->getOpcode() == llvm::Instruction::GetElementPtr) {
         llvm::Value *OpArg = GEPInstr->getOperand(0);
+        if (llvm::ConstantExpr *NewGEPInstr =
+                llvm::dyn_cast<llvm::ConstantExpr>(OpArg)) {
+          GEPInstr = NewGEPInstr;
+          continue;
+        }
 
         if (auto *GlobalVar = llvm::dyn_cast<llvm::GlobalVariable>(OpArg)) {
-          llvm::Constant *initializer = GlobalVar->getInitializer();
-
           llvm::Type *ValTy = GlobalVar->getValueType();
           if (auto *ArrTy = llvm::dyn_cast<llvm::ArrayType>(ValTy)) {
             llvm::Type *ElTy = ArrTy->getElementType();
@@ -181,6 +185,7 @@ class DXILPrepareModule : public ModulePass {
               return nullptr;
           }
         }
+        break;
       }
     }
 



More information about the llvm-commits mailing list