[llvm] f5d054c - Modify DXILPrepare to emit no-op bitcasts

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 11:41:00 PDT 2022


Author: Chris Bieneman
Date: 2022-05-09T13:40:47-05:00
New Revision: f5d054cdc12ef6c94a75c42400372ad525934bca

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

LOG: Modify DXILPrepare to emit no-op bitcasts

In supporting opaque pointers we need to re-materialize typed pointers
in bitcode emission. Because of how the value-enumerator pre-allocates
types and instructions we need to insert some no-op bitcasts in the
places that we'll need bitcasts for the pointer types.

Reviewed By: kuhar

Differential Revision: https://reviews.llvm.org/D122269

Added: 
    llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
    llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll

Modified: 
    llvm/lib/Target/DirectX/DXILPrepare.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
index 7f43051105cec..5da9f12117a40 100644
--- a/llvm/lib/Target/DirectX/DXILPrepare.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "DirectX.h"
+#include "PointerTypeAnalysis.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/Passes.h"
@@ -25,6 +26,7 @@
 #define DEBUG_TYPE "dxil-prepare"
 
 using namespace llvm;
+using namespace llvm::dxil;
 
 namespace {
 
@@ -78,8 +80,27 @@ constexpr bool isValidForDXIL(Attribute::AttrKind Attr) {
 }
 
 class DXILPrepareModule : public ModulePass {
+
+  static Value *maybeGenerateBitcast(IRBuilder<> &Builder,
+                                     PointerTypeMap &PointerTypes,
+                                     Instruction &Inst, Value *Operand,
+                                     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)
+        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
+    // pointer doesn't matter.
+    return Builder.Insert(CastInst::Create(Instruction::BitCast, Operand,
+                                           Builder.getInt8PtrTy()));
+  }
+
 public:
   bool runOnModule(Module &M) override {
+    PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M);
     AttributeMask AttrMask;
     for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
          I = Attribute::AttrKind(I + 1)) {
@@ -89,7 +110,7 @@ class DXILPrepareModule : public ModulePass {
     for (auto &F : M.functions()) {
       F.removeFnAttrs(AttrMask);
       F.removeRetAttrs(AttrMask);
-      for (size_t Idx = 0; Idx < F.arg_size(); ++Idx)
+      for (size_t Idx = 0, End = F.arg_size(); Idx < End; ++Idx)
         F.removeParamAttrs(Idx, AttrMask);
 
       for (auto &BB : F) {
@@ -101,6 +122,41 @@ class DXILPrepareModule : public ModulePass {
             Value *Zero = ConstantFP::get(In->getType(), -0.0);
             I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
             I.eraseFromParent();
+            continue;
+          }
+          // Only insert bitcasts if the IR is using opaque pointers.
+          if (!M.getContext().hasSetOpaquePointersValue())
+            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)) {
+            if (Value *NoOpBitcast = maybeGenerateBitcast(
+                    Builder, PointerTypes, I, LI->getPointerOperand(),
+                    LI->getType())) {
+              LI->replaceAllUsesWith(
+                  Builder.CreateLoad(LI->getType(), NoOpBitcast));
+              LI->eraseFromParent();
+            }
+            continue;
+          }
+          if (auto SI = dyn_cast<StoreInst>(&I)) {
+            if (Value *NoOpBitcast = maybeGenerateBitcast(
+                    Builder, PointerTypes, I, SI->getPointerOperand(),
+                    SI->getValueOperand()->getType())) {
+
+              SI->replaceAllUsesWith(
+                  Builder.CreateStore(SI->getValueOperand(), NoOpBitcast));
+              SI->eraseFromParent();
+            }
+            continue;
+          }
+          if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) {
+            if (Value *NoOpBitcast = maybeGenerateBitcast(
+                    Builder, PointerTypes, I, GEP->getPointerOperand(),
+                    GEP->getResultElementType()))
+              GEP->setOperand(0, NoOpBitcast);
+            continue;
           }
         }
       }

diff  --git a/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll b/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
new file mode 100644
index 0000000000000..76f2162c117bc
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/conflicting-bitcast-insert.ll
@@ -0,0 +1,26 @@
+; RUN: llc --filetype=asm %s -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define i64 @test(ptr %p) {
+  store i32 0, ptr %p
+  %v = load i64, ptr %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test(ptr %p) {
+; CHECK-NEXT: %1 = bitcast ptr %p to ptr
+; CHECK-NEXT: store i32 0, ptr %1, align 4
+; CHECK-NEXT: %2 = bitcast ptr %p to ptr
+; CHECK-NEXT: %3 = load i64, ptr %2, align 8
+
+define i64 @testGEP(ptr %p) {
+  %ptr = getelementptr i32, ptr %p, i32 4
+  %val = load i64, ptr %p
+  ret i64 %val
+}
+
+; CHECK: define i64 @testGEP(ptr %p) {
+; CHECK-NEXT:   %1 = bitcast ptr %p to ptr
+; CHECK-NEXT:   %ptr = getelementptr i32, ptr %1, i32 4
+; CHECK-NEXT:   %2 = bitcast ptr %p to ptr
+; CHECK-NEXT:   %3 = load i64, ptr %2, align 8

diff  --git a/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll b/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll
new file mode 100644
index 0000000000000..4b495b993800a
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/omit-bitcast-insert.ll
@@ -0,0 +1,32 @@
+; RUN: llc --filetype=asm %s -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define i64 @test(ptr %p) {
+  %v = load i64, ptr %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test(ptr %p) {
+; CHECK-NEXT: %v = load i64, ptr %p, align 8
+; CHECK-NEXT: ret i64 %v
+
+define i64 @test2(ptr %p) {
+  store i64 0, ptr %p
+  %v = load i64, ptr %p
+  ret i64 %v
+}
+
+; CHECK: define i64 @test2(ptr %p) {
+; CHECK-NEXT: store i64 0, ptr %p
+; CHECK-NEXT: %v = load i64, ptr %p, align 8
+; CHECK-NEXT: ret i64 %v
+
+define i32 @test3(ptr %0)  {
+  %2 = getelementptr i32, ptr %0, i32 4
+  %3 = load i32, ptr %2
+  ret i32 %3
+}
+
+; CHECK: define i32 @test3(ptr %0)  {
+; CHECK-NEXT: %2 = getelementptr i32, ptr %0, i32 4
+; CHECK-NEXT: %3 = load i32, ptr %2


        


More information about the llvm-commits mailing list