[llvm] d1edef5 - [SandboxIR] Functions to find vectorizor-relevant properties (#109221)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 23 11:05:26 PDT 2024
Author: Sterling-Augustine
Date: 2024-09-23T11:05:23-07:00
New Revision: d1edef56e87631ca8712afe01ac560710a2334f2
URL: https://github.com/llvm/llvm-project/commit/d1edef56e87631ca8712afe01ac560710a2334f2
DIFF: https://github.com/llvm/llvm-project/commit/d1edef56e87631ca8712afe01ac560710a2334f2.diff
LOG: [SandboxIR] Functions to find vectorizor-relevant properties (#109221)
When vectorizing, the destination type and value of stores is more
relevant than the type of the instruction itself. Similarly for return
instructions. These functions provide a convenient way to do that
without special-casing them everywhere, and avoids the need for
friending any class that needs access to Value::LLVMTy to calculate it.
Open to better naming.
Added:
llvm/include/llvm/SandboxIR/Utils.h
Modified:
llvm/include/llvm/SandboxIR/Type.h
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/Type.h b/llvm/include/llvm/SandboxIR/Type.h
index a2ac9e014b44ab..f99f80967797c1 100644
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ b/llvm/include/llvm/SandboxIR/Type.h
@@ -56,6 +56,7 @@ class Type {
friend class ConstantVector; // For LLVMTy.
friend class CmpInst; // For LLVMTy. TODO: Cleanup after
// sandboxir::VectorType is more complete.
+ friend class Utils; // for LLVMTy
// Friend all instruction classes because `create()` functions use LLVMTy.
#define DEF_INSTR(ID, OPCODE, CLASS) friend class CLASS;
diff --git a/llvm/include/llvm/SandboxIR/Utils.h b/llvm/include/llvm/SandboxIR/Utils.h
new file mode 100644
index 00000000000000..ccc0030868a55b
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/Utils.h
@@ -0,0 +1,54 @@
+//===- Utils.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Collector for SandboxIR related convenience functions that don't belong in
+// other classes.
+
+#ifndef LLVM_SANDBOXIR_UTILS_H
+#define LLVM_SANDBOXIR_UTILS_H
+
+namespace llvm::sandboxir {
+
+class Utils {
+public:
+ /// \Returns the expected type of \p Value V. For most Values this is
+ /// equivalent to getType, but for stores returns the stored type, rather
+ /// than void, and for ReturnInsts returns the returned type.
+ static Type *getExpectedType(const Value *V) {
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ // A Return's value operand can be null if it returns void.
+ if (auto *RI = dyn_cast<ReturnInst>(I)) {
+ if (RI->getReturnValue() == nullptr)
+ return RI->getType();
+ }
+ return getExpectedValue(I)->getType();
+ }
+ return V->getType();
+ }
+
+ /// \Returns the expected Value for this instruction. For most instructions,
+ /// this is the instruction itself, but for stores returns the stored
+ /// operand, and for ReturnInstructions returns the returned value.
+ static Value *getExpectedValue(const Instruction *I) {
+ if (auto *SI = dyn_cast<StoreInst>(I))
+ return SI->getValueOperand();
+ if (auto *RI = dyn_cast<ReturnInst>(I))
+ return RI->getReturnValue();
+ return const_cast<Instruction *>(I);
+ }
+
+ /// \Returns the number of bits required to represent the operands or return
+ /// value of \p V in \p DL.
+ static unsigned getNumBits(Value *V, const DataLayout &DL) {
+ Type *Ty = getExpectedType(V);
+ return DL.getTypeSizeInBits(Ty->LLVMTy);
+ }
+};
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_UTILS_H
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index bd6a4c29ebbb62..9088a0f7b80ea4 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -14,6 +14,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Module.h"
+#include "llvm/SandboxIR/Utils.h"
#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
@@ -1373,6 +1374,8 @@ OperandNo: 0
EXPECT_TRUE(I0->hasNUses(1u));
EXPECT_FALSE(I0->hasNUses(2u));
+ // Check Value.getExpectedType
+
// Check User.setOperand().
Ret->setOperand(0, Arg0);
EXPECT_EQ(Ret->getOperand(0), Arg0);
@@ -1436,7 +1439,6 @@ define i32 @foo(i32 %arg0, i32 %arg1) {
Replaced = Ret->replaceUsesOfWith(I0, Arg0);
EXPECT_TRUE(Replaced);
EXPECT_EQ(Ret->getOperand(0), Arg0);
-
// Check RAUW on constant.
auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand(0));
auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand(0));
@@ -1445,6 +1447,68 @@ define i32 @foo(i32 %arg0, i32 %arg1) {
EXPECT_EQ(Glob0->getOperand(0), Glob1);
}
+TEST_F(SandboxIRTest, GetExpected) {
+ parseIR(C, R"IR(
+define float @foo(float %v, ptr %ptr) {
+ %add = fadd float %v, %v
+ store float %v, ptr %ptr
+ ret float %v
+}
+define void @bar(float %v, ptr %ptr) {
+ ret void
+}
+)IR");
+ llvm::Function &Foo = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+
+ Ctx.createFunction(&Foo);
+ auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin()));
+ auto FooIt = FooBB->begin();
+ auto Add = cast<sandboxir::Instruction>(&*FooIt++);
+ auto *S0 = cast<sandboxir::Instruction>(&*FooIt++);
+ auto *RetF = cast<sandboxir::Instruction>(&*FooIt++);
+ // getExpectedValue
+ EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add);
+ EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0),
+ cast<sandboxir::StoreInst>(S0)->getValueOperand());
+ EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF),
+ cast<sandboxir::ReturnInst>(RetF)->getReturnValue());
+ // getExpectedType
+ EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType());
+ EXPECT_EQ(sandboxir::Utils::getExpectedType(S0),
+ cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType());
+ EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF),
+ cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType());
+
+ // getExpectedValue for void returns
+ llvm::Function &Bar = *M->getFunction("bar");
+ Ctx.createFunction(&Bar);
+ auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin()));
+ auto BarIt = BarBB->begin();
+ auto *RetV = cast<sandboxir::Instruction>(&*BarIt++);
+ EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr);
+}
+
+TEST_F(SandboxIRTest, GetNumBits) {
+ parseIR(C, R"IR(
+define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3) {
+bb0:
+ ret void
+}
+)IR");
+ llvm::Function &Foo = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ sandboxir::Function *F = Ctx.createFunction(&Foo);
+ const DataLayout &DL = M->getDataLayout();
+ // getNumBits for scalars
+ EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL),
+ DL.getTypeSizeInBits(Type::getFloatTy(C)));
+ EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL),
+ DL.getTypeSizeInBits(Type::getDoubleTy(C)));
+ EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u);
+ EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u);
+}
+
TEST_F(SandboxIRTest, RAUW_RUWIf) {
parseIR(C, R"IR(
define void @foo(ptr %ptr) {
More information about the llvm-commits
mailing list