[llvm] 6013d84 - [OpaquePtr] Make loads and stores work with opaque pointers
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Tue May 18 13:48:11 PDT 2021
Author: Arthur Eubanks
Date: 2021-05-18T13:43:50-07:00
New Revision: 6013d84392fa1b7683921f9d3b6aedb357233e06
URL: https://github.com/llvm/llvm-project/commit/6013d84392fa1b7683921f9d3b6aedb357233e06
DIFF: https://github.com/llvm/llvm-project/commit/6013d84392fa1b7683921f9d3b6aedb357233e06.diff
LOG: [OpaquePtr] Make loads and stores work with opaque pointers
Don't check that types match when the pointer operand is an opaque
pointer.
I would separate the Assembler and Verifier changes, but
verify-uselistorder in the Assembler test ends up running the verifier.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D102450
Added:
llvm/test/Verifier/opaque-ptr.ll
Modified:
llvm/include/llvm/IR/DerivedTypes.h
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/IR/Instructions.cpp
llvm/lib/IR/Verifier.cpp
llvm/test/Assembler/opaque-ptr.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index 1566b4264573..1904f8286ac4 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -676,6 +676,14 @@ class PointerType : public Type {
/// Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return getSubclassData(); }
+ /// Return true if either this is an opaque pointer type or if this pointee
+ /// type matches Ty. Primarily used for checking if an instruction's pointer
+ /// operands are valid types. Will be useless after non-opaque pointers are
+ /// removed.
+ bool isOpaqueOrPointeeTypeMatches(Type *Ty) {
+ return isOpaque() || PointeeTy == Ty;
+ }
+
/// Implement support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Type *T) {
return T->getTypeID() == PointerTyID;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index ca3efa8e662d..2f85e8de575f 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -7483,7 +7483,7 @@ int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Ordering == AtomicOrdering::AcquireRelease)
return error(Loc, "atomic load cannot use Release ordering");
- if (Ty != cast<PointerType>(Val->getType())->getElementType()) {
+ if (!cast<PointerType>(Val->getType())->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
ExplicitTypeLoc,
typeComparisonErrorMessage(
@@ -7534,7 +7534,8 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
return error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return error(Loc, "store operand must be a first class value");
- if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Val->getType()))
return error(Loc, "stored value and pointer type do not match");
if (isAtomic && !Alignment)
return error(Loc, "atomic store must have explicit non-zero alignment");
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 25edf24037cb..b2794b38bd4e 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3844,12 +3844,11 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
if (!isa<PointerType>(PtrType))
return error("Load/Store operand is not a pointer type");
- Type *ElemType = cast<PointerType>(PtrType)->getElementType();
- if (ValType && ValType != ElemType)
+ if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType))
return error("Explicit load/store type does not match pointee "
"type of pointer operand");
- if (!PointerType::isLoadableOrStorableType(ElemType))
+ if (!PointerType::isLoadableOrStorableType(ValType))
return error("Cannot load/store from pointer");
return Error::success();
}
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 6abe9135614a..134a023f81d9 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1436,7 +1436,7 @@ LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
Align Align, AtomicOrdering Order, SyncScope::ID SSID,
Instruction *InsertBef)
: UnaryInstruction(Ty, Load, Ptr, InsertBef) {
- assert(Ty == cast<PointerType>(Ptr->getType())->getElementType());
+ assert(cast<PointerType>(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty));
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SSID);
@@ -1448,7 +1448,7 @@ LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
Align Align, AtomicOrdering Order, SyncScope::ID SSID,
BasicBlock *InsertAE)
: UnaryInstruction(Ty, Load, Ptr, InsertAE) {
- assert(Ty == cast<PointerType>(Ptr->getType())->getElementType());
+ assert(cast<PointerType>(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty));
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SSID);
@@ -1464,9 +1464,9 @@ void StoreInst::AssertOK() {
assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
assert(getOperand(1)->getType()->isPointerTy() &&
"Ptr must have pointer type!");
- assert(getOperand(0)->getType() ==
- cast<PointerType>(getOperand(1)->getType())->getElementType()
- && "Ptr must be a pointer to Val type!");
+ assert(cast<PointerType>(getOperand(1)->getType())
+ ->isOpaqueOrPointeeTypeMatches(getOperand(0)->getType()) &&
+ "Ptr must be a pointer to Val type!");
assert(!(isAtomic() && getAlignment() == 0) &&
"Alignment required for atomic store");
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index de28c26898e2..986d7ec10a81 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3753,8 +3753,8 @@ void Verifier::visitLoadInst(LoadInst &LI) {
void Verifier::visitStoreInst(StoreInst &SI) {
PointerType *PTy = dyn_cast<PointerType>(SI.getOperand(1)->getType());
Assert(PTy, "Store operand must be a pointer.", &SI);
- Type *ElTy = PTy->getElementType();
- Assert(ElTy == SI.getOperand(0)->getType(),
+ Type *ElTy = SI.getOperand(0)->getType();
+ Assert(PTy->isOpaqueOrPointeeTypeMatches(ElTy),
"Stored value type does not match pointer operand type!", &SI, ElTy);
Assert(SI.getAlignment() <= Value::MaximumAlignment,
"huge alignment values are unsupported", &SI);
diff --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 82fcf9f21a6e..95a5a53e80b7 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -24,3 +24,19 @@ define ptr addrspace(2) @g2(ptr addrspace(0) %a) {
%b = addrspacecast ptr addrspace(0) %a to ptr addrspace(2)
ret ptr addrspace(2) %b
}
+
+; CHECK: define i32 @load(ptr %a)
+; CHECK: %i = load i32, ptr %a
+; CHECK: ret i32 %i
+define i32 @load(ptr %a) {
+ %i = load i32, ptr %a
+ ret i32 %i
+}
+
+; CHECK: define void @store(ptr %a, i32 %i)
+; CHECK: store i32 %i, ptr %a
+; CHECK: ret void
+define void @store(ptr %a, i32 %i) {
+ store i32 %i, ptr %a
+ ret void
+}
diff --git a/llvm/test/Verifier/opaque-ptr.ll b/llvm/test/Verifier/opaque-ptr.ll
new file mode 100644
index 000000000000..ff25a8c940fd
--- /dev/null
+++ b/llvm/test/Verifier/opaque-ptr.ll
@@ -0,0 +1,13 @@
+; RUN: opt -passes=verify -S < %s | FileCheck %s
+
+; CHECK: @load
+define i32 @load(ptr %a) {
+ %i = load i32, ptr %a
+ ret i32 %i
+}
+
+; CHECK: @store
+define void @store(ptr %a, i32 %i) {
+ store i32 %i, ptr %a
+ ret void
+}
More information about the llvm-commits
mailing list