[llvm] fd2da9e - [SandboxIR] Implement PoisonValue (#107324)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 6 11:26:23 PDT 2024


Author: vporpo
Date: 2024-09-06T11:26:20-07:00
New Revision: fd2da9e5818ec6e53100f92c9eb6ed4f1b0b99eb

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

LOG: [SandboxIR] Implement PoisonValue (#107324)

This patch implements sandboxir::PoisonValue mirroring
llvm::PoisonValue.

Added: 
    

Modified: 
    llvm/include/llvm/SandboxIR/SandboxIR.h
    llvm/include/llvm/SandboxIR/SandboxIRValues.def
    llvm/lib/SandboxIR/SandboxIR.cpp
    llvm/unittests/SandboxIR/SandboxIRTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 4db4fae24b4b34..bede697670a281 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -122,6 +122,7 @@ class ConstantInt;
 class ConstantFP;
 class ConstantAggregateZero;
 class ConstantPointerNull;
+class PoisonValue;
 class Context;
 class Function;
 class Instruction;
@@ -320,6 +321,7 @@ class Value {
   friend class ConstantStruct;        // For `Val`.
   friend class ConstantAggregateZero; // For `Val`.
   friend class ConstantPointerNull;   // For `Val`.
+  friend class PoisonValue;           // For `Val`.
 
   /// All values point to the context.
   Context &Ctx;
@@ -1018,6 +1020,49 @@ class ConstantPointerNull final : public Constant {
 #endif
 };
 
+// TODO: Inherit from UndefValue.
+class PoisonValue final : public Constant {
+  PoisonValue(llvm::PoisonValue *C, Context &Ctx)
+      : Constant(ClassID::PoisonValue, C, Ctx) {}
+  friend class Context; // For constructor.
+
+public:
+  /// Static factory methods - Return an 'poison' object of the specified type.
+  static PoisonValue *get(Type *T);
+
+  /// If this poison has array or vector type, return a poison with the right
+  /// element type.
+  PoisonValue *getSequentialElement() const;
+
+  /// If this poison has struct type, return a poison with the right element
+  /// type for the specified element.
+  PoisonValue *getStructElement(unsigned Elt) const;
+
+  /// Return an poison of the right value for the specified GEP index if we can,
+  /// otherwise return null (e.g. if C is a ConstantExpr).
+  PoisonValue *getElementValue(Constant *C) const;
+
+  /// Return an poison of the right value for the specified GEP index.
+  PoisonValue *getElementValue(unsigned Idx) const;
+
+  /// For isa/dyn_cast.
+  static bool classof(const sandboxir::Value *From) {
+    return From->getSubclassID() == ClassID::PoisonValue;
+  }
+  unsigned getUseOperandNo(const Use &Use) const final {
+    llvm_unreachable("PoisonValue has no operands!");
+  }
+#ifndef NDEBUG
+  void verify() const override {
+    assert(isa<llvm::PoisonValue>(Val) && "Expected a PoisonValue!");
+  }
+  void dumpOS(raw_ostream &OS) const override {
+    dumpCommonPrefix(OS);
+    dumpCommonSuffix(OS);
+  }
+#endif
+};
+
 /// Iterator for `Instruction`s in a `BasicBlock.
 /// \Returns an sandboxir::Instruction & when derereferenced.
 class BBIterator {

diff  --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index fce5aacc8c86d4..5acf7bfe08f5ae 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -32,6 +32,7 @@ DEF_CONST(ConstantStruct, ConstantStruct)
 DEF_CONST(ConstantVector, ConstantVector)
 DEF_CONST(ConstantAggregateZero, ConstantAggregateZero)
 DEF_CONST(ConstantPointerNull, ConstantPointerNull)
+DEF_CONST(PoisonValue, PoisonValue)
 
 #ifndef DEF_INSTR
 #define DEF_INSTR(ID, OPCODE, CLASS)

diff  --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index acbc5c17ab2568..4ba3ab7a0ce43b 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2437,6 +2437,32 @@ PointerType *ConstantPointerNull::getType() const {
       Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));
 }
 
+PoisonValue *PoisonValue::get(Type *T) {
+  auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy);
+  return cast<PoisonValue>(T->getContext().getOrCreateConstant(LLVMC));
+}
+
+PoisonValue *PoisonValue::getSequentialElement() const {
+  return cast<PoisonValue>(Ctx.getOrCreateConstant(
+      cast<llvm::PoisonValue>(Val)->getSequentialElement()));
+}
+
+PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
+  return cast<PoisonValue>(Ctx.getOrCreateConstant(
+      cast<llvm::PoisonValue>(Val)->getStructElement(Elt)));
+}
+
+PoisonValue *PoisonValue::getElementValue(Constant *C) const {
+  return cast<PoisonValue>(
+      Ctx.getOrCreateConstant(cast<llvm::PoisonValue>(Val)->getElementValue(
+          cast<llvm::Constant>(C->Val))));
+}
+
+PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
+  return cast<PoisonValue>(Ctx.getOrCreateConstant(
+      cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
+}
+
 FunctionType *Function::getFunctionType() const {
   return cast<FunctionType>(
       Ctx.getType(cast<llvm::Function>(Val)->getFunctionType()));
@@ -2550,6 +2576,10 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
       It->second = std::unique_ptr<ConstantPointerNull>(
           new ConstantPointerNull(cast<llvm::ConstantPointerNull>(C), *this));
       return It->second.get();
+    case llvm::Value::PoisonValueVal:
+      It->second = std::unique_ptr<PoisonValue>(
+          new PoisonValue(cast<llvm::PoisonValue>(C), *this));
+      return It->second.get();
     case llvm::Value::ConstantArrayVal:
       It->second = std::unique_ptr<ConstantArray>(
           new ConstantArray(cast<llvm::ConstantArray>(C), *this));

diff  --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 2f5ef92578e775..1c0b9f83ab629a 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -616,6 +616,60 @@ define ptr @foo() {
   EXPECT_EQ(NewCPNull2->getType(), sandboxir::PointerType::get(Ctx, 1u));
 }
 
+TEST_F(SandboxIRTest, PoisonValue) {
+  parseIR(C, R"IR(
+define void @foo() {
+  %i0 = add i32 poison, poison
+  %i1 = add <2 x i32> poison, poison
+  %i2 = extractvalue {i32, i8} poison, 0
+  ret void
+}
+)IR");
+  Function &LLVMF = *M->getFunction("foo");
+  sandboxir::Context Ctx(C);
+
+  auto &F = *Ctx.createFunction(&LLVMF);
+  auto &BB = *F.begin();
+  auto It = BB.begin();
+  auto *I0 = &*It++;
+  auto *I1 = &*It++;
+  auto *I2 = &*It++;
+  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
+  auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
+  auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u);
+  auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u);
+
+  // Check classof() and creation.
+  auto *Poison = cast<sandboxir::PoisonValue>(I0->getOperand(0));
+  EXPECT_EQ(Poison->getType(), Int32Ty);
+  // Check get().
+  auto *NewPoison = sandboxir::PoisonValue::get(Int32Ty);
+  EXPECT_EQ(NewPoison, Poison);
+  auto *NewPoison2 =
+      sandboxir::PoisonValue::get(sandboxir::PointerType::get(Ctx, 0u));
+  EXPECT_NE(NewPoison2, Poison);
+  // Check getSequentialElement().
+  auto *PoisonVector = cast<sandboxir::PoisonValue>(I1->getOperand(0));
+  auto *SeqElm = PoisonVector->getSequentialElement();
+  EXPECT_EQ(SeqElm->getType(), Int32Ty);
+  // Check getStructElement().
+  auto *PoisonStruct = cast<sandboxir::PoisonValue>(I2->getOperand(0));
+  auto *StrElm0 = PoisonStruct->getStructElement(0);
+  auto *StrElm1 = PoisonStruct->getStructElement(1);
+  EXPECT_EQ(StrElm0->getType(), Int32Ty);
+  EXPECT_EQ(StrElm1->getType(), Int8Ty);
+  // Check getElementValue(Constant)
+  EXPECT_EQ(PoisonStruct->getElementValue(Zero32),
+            sandboxir::PoisonValue::get(Int32Ty));
+  EXPECT_EQ(PoisonStruct->getElementValue(One32),
+            sandboxir::PoisonValue::get(Int8Ty));
+  // Check getElementValue(unsigned)
+  EXPECT_EQ(PoisonStruct->getElementValue(0u),
+            sandboxir::PoisonValue::get(Int32Ty));
+  EXPECT_EQ(PoisonStruct->getElementValue(1u),
+            sandboxir::PoisonValue::get(Int8Ty));
+}
+
 TEST_F(SandboxIRTest, Use) {
   parseIR(C, R"IR(
 define i32 @foo(i32 %v0, i32 %v1) {


        


More information about the llvm-commits mailing list