[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