[llvm] [SandboxIR] Implement BitCastInst (PR #101227)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 30 15:20:25 PDT 2024


https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/101227

>From a7c9be01f6ace6fa95d06ccc6f8a973de09c378a Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 25 Jul 2024 16:41:11 -0700
Subject: [PATCH] [SandboxIR] Implement BitCastInst

This patch implements sandboxir::BitCastInst which mirrors llvm::BitCastInst.
---
 llvm/include/llvm/SandboxIR/SandboxIR.h    | 27 ++++++++-
 llvm/lib/SandboxIR/SandboxIR.cpp           | 31 ++++++++++
 llvm/unittests/SandboxIR/SandboxIRTest.cpp | 70 ++++++++++++++++++++++
 3 files changed, 127 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 5c395f0962a90..5b2330c35ee23 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -28,7 +28,9 @@
 //                                      |
 //                                      +- BranchInst
 //                                      |
-//                                      +- CastInst ------------- PtrToIntInst
+//                                      +- CastInst -----------+- BitCastInst
+//                                      |                      |
+//                                      |                      +- PtrToIntInst
 //                                      |
 //                                      +- CallBase -----------+- CallBrInst
 //                                      |                      |
@@ -96,6 +98,7 @@ class CallBrInst;
 class GetElementPtrInst;
 class CastInst;
 class PtrToIntInst;
+class BitCastInst;
 
 /// Iterator for the `Use` edges of a User's operands.
 /// \Returns the operand `Use` when dereferenced.
@@ -1376,6 +1379,7 @@ class PtrToIntInst final : public CastInst {
                        Context &Ctx, const Twine &Name = "");
   static Value *create(Value *Src, Type *DestTy, BasicBlock *InsertAtEnd,
                        Context &Ctx, const Twine &Name = "");
+
   static bool classof(const Value *From) {
     return isa<Instruction>(From) &&
            cast<Instruction>(From)->getOpcode() == Opcode::PtrToInt;
@@ -1386,6 +1390,27 @@ class PtrToIntInst final : public CastInst {
 #endif // NDEBUG
 };
 
+class BitCastInst : public CastInst {
+public:
+  static Value *create(Value *Src, Type *DestTy, BBIterator WhereIt,
+                       BasicBlock *WhereBB, Context &Ctx,
+                       const Twine &Name = "");
+  static Value *create(Value *Src, Type *DestTy, Instruction *InsertBefore,
+                       Context &Ctx, const Twine &Name = "");
+  static Value *create(Value *Src, Type *DestTy, BasicBlock *InsertAtEnd,
+                       Context &Ctx, const Twine &Name = "");
+
+  static bool classof(const Value *From) {
+    if (auto *I = dyn_cast<Instruction>(From))
+      return I->getOpcode() == Instruction::Opcode::BitCast;
+    return false;
+  }
+#ifndef NDEBUG
+  void dump(raw_ostream &OS) const override;
+  LLVM_DUMP_METHOD void dump() const override;
+#endif
+};
+
 /// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
 /// an OpaqueInstr.
 class OpaqueInst : public sandboxir::Instruction {
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 1e31c922b9a97..010cc115a5cc3 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -1169,6 +1169,37 @@ void PtrToIntInst::dump() const {
   dump(dbgs());
   dbgs() << "\n";
 }
+#endif // NDEBUG
+
+Value *BitCastInst::create(Value *Src, Type *DestTy, BBIterator WhereIt,
+                           BasicBlock *WhereBB, Context &Ctx,
+                           const Twine &Name) {
+  return CastInst::create(DestTy, Instruction::Opcode::BitCast, Src, WhereIt,
+                          WhereBB, Ctx, Name);
+}
+
+Value *BitCastInst::create(Value *Src, Type *DestTy, Instruction *InsertBefore,
+                           Context &Ctx, const Twine &Name) {
+  return CastInst::create(DestTy, Instruction::Opcode::BitCast, Src,
+                          InsertBefore, Ctx, Name);
+}
+
+Value *BitCastInst::create(Value *Src, Type *DestTy, BasicBlock *InsertAtEnd,
+                           Context &Ctx, const Twine &Name) {
+  return CastInst::create(DestTy, Instruction::Opcode::BitCast, Src,
+                          InsertAtEnd, Ctx, Name);
+}
+
+#ifndef NDEBUG
+void BitCastInst::dump(raw_ostream &OS) const {
+  dumpCommonPrefix(OS);
+  dumpCommonSuffix(OS);
+}
+
+void BitCastInst::dump() const {
+  dump(dbgs());
+  dbgs() << "\n";
+}
 
 void OpaqueInst::dump(raw_ostream &OS) const {
   dumpCommonPrefix(OS);
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 9ca62e8caa3f6..28c3aebeb1862 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1545,6 +1545,7 @@ define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
   EXPECT_EQ(FPTrunc->getDestTy(), Tfloat);
 
   auto *BitCast = cast<sandboxir::CastInst>(&*It++);
+  EXPECT_TRUE(isa<sandboxir::BitCastInst>(BitCast));
   EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
   EXPECT_EQ(BitCast->getSrcTy(), Ti32);
   EXPECT_EQ(BitCast->getDestTy(), Tfloat);
@@ -1682,3 +1683,72 @@ define void @foo(ptr %ptr) {
     EXPECT_EQ(NewI->getParent(), BB);
   }
 }
+
+TEST_F(SandboxIRTest, BitCastInst) {
+  parseIR(C, R"IR(
+define void @foo(i32 %arg) {
+  %bitcast = bitcast i32 %arg to float
+  ret void
+}
+)IR");
+  Function &LLVMF = *M->getFunction("foo");
+  sandboxir::Context Ctx(C);
+  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
+  unsigned ArgIdx = 0;
+  auto *Arg = F->getArg(ArgIdx++);
+  auto *BB = &*F->begin();
+  auto It = BB->begin();
+  Type *Ti32 = Type::getInt32Ty(C);
+  Type *Tfloat = Type::getFloatTy(C);
+
+  auto *BitCast = cast<sandboxir::BitCastInst>(&*It++);
+  EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
+  EXPECT_EQ(BitCast->getSrcTy(), Ti32);
+  EXPECT_EQ(BitCast->getDestTy(), Tfloat);
+  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
+
+  {
+    // Check create() WhereIt, WhereBB
+    auto *NewI = cast<sandboxir::BitCastInst>(
+        sandboxir::BitCastInst::create(Arg, Tfloat, /*WhereIt=*/BB->end(),
+                                       /*WhereBB=*/BB, Ctx, "BitCast"));
+    // Check getOpcode().
+    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
+    // Check getSrcTy().
+    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
+    // Check getDestTy().
+    EXPECT_EQ(NewI->getDestTy(), Tfloat);
+    // Check instr position.
+    EXPECT_EQ(NewI->getNextNode(), nullptr);
+    EXPECT_EQ(NewI->getPrevNode(), Ret);
+  }
+  {
+    // Check create() InsertBefore.
+    auto *NewI = cast<sandboxir::BitCastInst>(
+        sandboxir::BitCastInst::create(Arg, Tfloat,
+                                       /*InsertBefore=*/Ret, Ctx, "BitCast"));
+    // Check getOpcode().
+    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
+    // Check getSrcTy().
+    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
+    // Check getDestTy().
+    EXPECT_EQ(NewI->getDestTy(), Tfloat);
+    // Check instr position.
+    EXPECT_EQ(NewI->getNextNode(), Ret);
+  }
+  {
+    // Check create() InsertAtEnd.
+    auto *NewI = cast<sandboxir::BitCastInst>(
+        sandboxir::BitCastInst::create(Arg, Tfloat,
+                                       /*InsertAtEnd=*/BB, Ctx, "BitCast"));
+    // Check getOpcode().
+    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
+    // Check getSrcTy().
+    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
+    // Check getDestTy().
+    EXPECT_EQ(NewI->getDestTy(), Tfloat);
+    // Check instr position.
+    EXPECT_EQ(NewI->getNextNode(), nullptr);
+    EXPECT_EQ(NewI->getParent(), BB);
+  }
+}



More information about the llvm-commits mailing list