[llvm] [SandboxIR] Implement Operator (PR #112805)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 23:44:21 PDT 2024
https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/112805
>From 263e39125898c35c771a69cfcc066edd328f01a4 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 17 Oct 2024 15:02:48 -0700
Subject: [PATCH] [SandboxIR] Implement Operator
This patch implements sandboxir::Operator mirroring llvm::Operator.
---
llvm/include/llvm/SandboxIR/Operator.h | 60 ++++++++++++++++
llvm/include/llvm/SandboxIR/Value.h | 4 ++
llvm/unittests/SandboxIR/CMakeLists.txt | 1 +
llvm/unittests/SandboxIR/OperatorTest.cpp | 88 +++++++++++++++++++++++
4 files changed, 153 insertions(+)
create mode 100644 llvm/include/llvm/SandboxIR/Operator.h
create mode 100644 llvm/unittests/SandboxIR/OperatorTest.cpp
diff --git a/llvm/include/llvm/SandboxIR/Operator.h b/llvm/include/llvm/SandboxIR/Operator.h
new file mode 100644
index 00000000000000..95c450807191b4
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/Operator.h
@@ -0,0 +1,60 @@
+//===- Operator.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SANDBOXIR_OPERATOR_H
+#define LLVM_SANDBOXIR_OPERATOR_H
+
+#include "llvm/IR/Operator.h"
+#include "llvm/SandboxIR/Instruction.h"
+#include "llvm/SandboxIR/User.h"
+
+namespace llvm::sandboxir {
+
+class Operator : public User {
+public:
+ // The Operator class is intended to be used as a utility, and is never itself
+ // instantiated.
+ Operator() = delete;
+ void *operator new(size_t s) = delete;
+
+ static bool classof(const Instruction *) { return true; }
+ static bool classof(const ConstantExpr *) { return true; }
+ static bool classof(const Value *From) {
+ return llvm::Operator::classof(From->Val);
+ }
+ bool hasPoisonGeneratingFlags() const {
+ return cast<llvm::Operator>(Val)->hasPoisonGeneratingFlags();
+ }
+};
+
+class OverflowingBinaryOperator : public Operator {
+public:
+ bool hasNoUnsignedWrap() const {
+ return cast<llvm::OverflowingBinaryOperator>(Val)->hasNoUnsignedWrap();
+ }
+ bool hasNoSignedWrap() const {
+ return cast<llvm::OverflowingBinaryOperator>(Val)->hasNoSignedWrap();
+ }
+ unsigned getNoWrapKind() const {
+ return cast<llvm::OverflowingBinaryOperator>(Val)->getNoWrapKind();
+ }
+ static bool classof(const Instruction *From) {
+ return llvm::OverflowingBinaryOperator::classof(
+ cast<llvm::Instruction>(From->Val));
+ }
+ static bool classof(const ConstantExpr *From) {
+ return llvm::OverflowingBinaryOperator::classof(
+ cast<llvm::ConstantExpr>(From->Val));
+ }
+ static bool classof(const Value *From) {
+ return llvm::OverflowingBinaryOperator::classof(From->Val);
+ }
+};
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_OPERATOR_H
diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
index 3509f2a8d83650..58088684bf18ec 100644
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ b/llvm/include/llvm/SandboxIR/Value.h
@@ -28,6 +28,8 @@ class Module;
class UnaryInstruction;
class CmpInst;
class IntrinsicInst;
+class Operator;
+class OverflowingBinaryOperator;
/// Iterator for the `Use` edges of a Value's users.
/// \Returns a `Use` when dereferenced.
@@ -158,6 +160,8 @@ class Value {
friend class Utils; // For `Val`.
friend class Module; // For `Val`.
friend class IntrinsicInst; // For `Val`.
+ friend class Operator; // For `Val`.
+ friend class OverflowingBinaryOperator; // For `Val`.
// Region needs to manipulate metadata in the underlying LLVM Value, we don't
// expose metadata in sandboxir.
friend class Region;
diff --git a/llvm/unittests/SandboxIR/CMakeLists.txt b/llvm/unittests/SandboxIR/CMakeLists.txt
index 1e83bda7a1f6d1..b20ef829ed0c95 100644
--- a/llvm/unittests/SandboxIR/CMakeLists.txt
+++ b/llvm/unittests/SandboxIR/CMakeLists.txt
@@ -9,6 +9,7 @@ add_llvm_unittest(SandboxIRTests
IntrinsicInstTest.cpp
PassTest.cpp
RegionTest.cpp
+ OperatorTest.cpp
SandboxIRTest.cpp
TrackerTest.cpp
TypesTest.cpp
diff --git a/llvm/unittests/SandboxIR/OperatorTest.cpp b/llvm/unittests/SandboxIR/OperatorTest.cpp
new file mode 100644
index 00000000000000..031e2adf406927
--- /dev/null
+++ b/llvm/unittests/SandboxIR/OperatorTest.cpp
@@ -0,0 +1,88 @@
+//===- OperatorTest.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/SandboxIR/Operator.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/SandboxIR/Context.h"
+#include "llvm/SandboxIR/Function.h"
+#include "llvm/SandboxIR/Instruction.h"
+#include "llvm/SandboxIR/Module.h"
+#include "llvm/SandboxIR/Value.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+struct OperatorTest : public testing::Test {
+ LLVMContext C;
+ std::unique_ptr<Module> M;
+
+ void parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ M = parseAssemblyString(IR, Err, C);
+ if (!M)
+ Err.print("OperatorTest", errs());
+ }
+ BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
+ for (BasicBlock &BB : F)
+ if (BB.getName() == Name)
+ return &BB;
+ llvm_unreachable("Expected to find basic block!");
+ }
+};
+
+TEST_F(OperatorTest, Operator) {
+ parseIR(C, R"IR(
+define void @foo(i8 %v1) {
+ %add0 = add i8 %v1, 42
+ %add1 = add nuw i8 %v1, 42
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *OperatorI0 = cast<sandboxir::Operator>(&*It++);
+ auto *OperatorI1 = cast<sandboxir::Operator>(&*It++);
+ EXPECT_FALSE(OperatorI0->hasPoisonGeneratingFlags());
+ EXPECT_TRUE(OperatorI1->hasPoisonGeneratingFlags());
+}
+
+TEST_F(OperatorTest, OverflowingBinaryOperator) {
+ parseIR(C, R"IR(
+define void @foo(i8 %v1) {
+ %add = add i8 %v1, 42
+ %addNSW = add nsw i8 %v1, 42
+ %addNUW = add nuw i8 %v1, 42
+ ret void
+}
+)IR");
+ llvm::Function *LLVMF = &*M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(LLVMF);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Add = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
+ auto *AddNSW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
+ auto *AddNUW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
+ EXPECT_FALSE(Add->hasNoUnsignedWrap());
+ EXPECT_FALSE(Add->hasNoSignedWrap());
+ EXPECT_EQ(Add->getNoWrapKind(), llvm::OverflowingBinaryOperator::AnyWrap);
+
+ EXPECT_FALSE(AddNSW->hasNoUnsignedWrap());
+ EXPECT_TRUE(AddNSW->hasNoSignedWrap());
+ EXPECT_EQ(AddNSW->getNoWrapKind(),
+ llvm::OverflowingBinaryOperator::NoSignedWrap);
+
+ EXPECT_TRUE(AddNUW->hasNoUnsignedWrap());
+ EXPECT_FALSE(AddNUW->hasNoSignedWrap());
+ EXPECT_EQ(AddNUW->getNoWrapKind(),
+ llvm::OverflowingBinaryOperator::NoUnsignedWrap);
+}
More information about the llvm-commits
mailing list