[llvm] d65a700 - OpaquePtr: Add helpers for sret to mirror byval
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 06:57:34 PDT 2020
Author: Matt Arsenault
Date: 2020-09-24T09:57:28-04:00
New Revision: d65a7003c435de22b8e30dca292160fea822d887
URL: https://github.com/llvm/llvm-project/commit/d65a7003c435de22b8e30dca292160fea822d887
DIFF: https://github.com/llvm/llvm-project/commit/d65a7003c435de22b8e30dca292160fea822d887.diff
LOG: OpaquePtr: Add helpers for sret to mirror byval
Sret should really have a type parameter like byval does.
Added:
Modified:
llvm/include/llvm/IR/Argument.h
llvm/include/llvm/IR/Function.h
llvm/lib/Analysis/Lint.cpp
llvm/lib/IR/Function.cpp
llvm/lib/IR/Value.cpp
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/test/CodeGen/X86/vectorcall.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h
index 2dd7c6cbc8b8..f59a498dc75d 100644
--- a/llvm/include/llvm/IR/Argument.h
+++ b/llvm/include/llvm/IR/Argument.h
@@ -83,8 +83,8 @@ class Argument final : public Value {
/// in-memory ABI size copied to the stack for the call. Otherwise, return 0.
uint64_t getPassPointeeByValueCopySize(const DataLayout &DL) const;
- /// Return true if this argument has the byval, inalloca, preallocated, or
- /// byref attribute. These attributes represent arguments being passed by
+ /// Return true if this argument has the byval, sret, inalloca, preallocated,
+ /// or byref attribute. These attributes represent arguments being passed by
/// value (which may or may not involve a stack copy)
bool hasPointeeInMemoryValueAttr() const;
@@ -103,6 +103,9 @@ class Argument final : public Value {
/// If this is a byval argument, return its type.
Type *getParamByValType() const;
+ /// If this is an sret argument, return its type.
+ Type *getParamStructRetType() const;
+
/// If this is a byref argument, return its type.
Type *getParamByRefType() const;
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 85c0fe0cc89c..00803ccf6271 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -472,6 +472,12 @@ class Function : public GlobalObject, public ilist_node<Function> {
return Ty ? Ty : (arg_begin() + ArgNo)->getType()->getPointerElementType();
}
+ /// Extract the sret type for a parameter.
+ Type *getParamStructRetType(unsigned ArgNo) const {
+ // FIXME: Add type to attribute like byval
+ return (arg_begin() + ArgNo)->getType()->getPointerElementType();
+ }
+
/// Extract the byref type for a parameter.
Type *getParamByRefType(unsigned ArgNo) const {
return AttributeSets.getParamByRefType(ArgNo);
diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp
index 75b8f31c8a31..1f3970e00c74 100644
--- a/llvm/lib/Analysis/Lint.cpp
+++ b/llvm/lib/Analysis/Lint.cpp
@@ -250,7 +250,7 @@ void Lint::visitCallBase(CallBase &I) {
// Check that an sret argument points to valid memory.
if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
- Type *Ty = cast<PointerType>(Formal->getType())->getElementType();
+ Type *Ty = Formal->getParamStructRetType();
visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty),
DL->getABITypeAlign(Ty), Ty,
MemRef::Read | MemRef::Write);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index ec1000cb3f3a..16cf1bd8a117 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -140,12 +140,13 @@ bool Argument::hasPointeeInMemoryValueAttr() const {
return false;
AttributeList Attrs = getParent()->getAttributes();
return Attrs.hasParamAttribute(getArgNo(), Attribute::ByVal) ||
+ Attrs.hasParamAttribute(getArgNo(), Attribute::StructRet) ||
Attrs.hasParamAttribute(getArgNo(), Attribute::InAlloca) ||
Attrs.hasParamAttribute(getArgNo(), Attribute::Preallocated) ||
Attrs.hasParamAttribute(getArgNo(), Attribute::ByRef);
}
-/// For a byval, inalloca, or preallocated parameter, get the in-memory
+/// For a byval, sret, inalloca, or preallocated parameter, get the in-memory
/// parameter type.
static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
// FIXME: All the type carrying attributes are mutually exclusive, so there
@@ -157,10 +158,11 @@ static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) {
if (Type *PreAllocTy = ParamAttrs.getPreallocatedType())
return PreAllocTy;
- // FIXME: inalloca always depends on pointee element type. It's also possible
- // for byval to miss it.
+ // FIXME: sret and inalloca always depends on pointee element type. It's also
+ // possible for byval to miss it.
if (ParamAttrs.hasAttribute(Attribute::InAlloca) ||
ParamAttrs.hasAttribute(Attribute::ByVal) ||
+ ParamAttrs.hasAttribute(Attribute::StructRet) ||
ParamAttrs.hasAttribute(Attribute::Preallocated))
return cast<PointerType>(ArgTy)->getElementType();
@@ -196,6 +198,11 @@ Type *Argument::getParamByValType() const {
return getParent()->getParamByValType(getArgNo());
}
+Type *Argument::getParamStructRetType() const {
+ assert(getType()->isPointerTy() && "Only pointers have sret types");
+ return getParent()->getParamStructRetType(getArgNo());
+}
+
Type *Argument::getParamByRefType() const {
assert(getType()->isPointerTy() && "Only pointers have byval types");
return getParent()->getParamByRefType(getArgNo());
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 1ef33605cb51..545404fc9ba0 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -804,7 +804,7 @@ Align Value::getPointerAlignment(const DataLayout &DL) const {
const MaybeAlign Alignment = A->getParamAlign();
if (!Alignment && A->hasStructRetAttr()) {
// An sret parameter has at least the ABI alignment of the return type.
- Type *EltTy = cast<PointerType>(A->getType())->getElementType();
+ Type *EltTy = A->getParamStructRetType();
if (EltTy->isSized())
return DL.getABITypeAlign(EltTy);
}
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 9011e36619d9..0d66092a7035 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -813,7 +813,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpy, Value *cpyDest,
if (!A->hasStructRetAttr())
return false;
- Type *StructTy = cast<PointerType>(A->getType())->getElementType();
+ Type *StructTy = A->getParamStructRetType();
if (!StructTy->isSized()) {
// The call may never return and hence the copy-instruction may never
// be executed, and therefore it's not safe to say "the destination
diff --git a/llvm/test/CodeGen/X86/vectorcall.ll b/llvm/test/CodeGen/X86/vectorcall.ll
index da474d028888..4a375acc4b97 100644
--- a/llvm/test/CodeGen/X86/vectorcall.ll
+++ b/llvm/test/CodeGen/X86/vectorcall.ll
@@ -172,7 +172,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture r
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1)
define x86_vectorcallcc void @test_mixed_7(%struct.HVA5* noalias sret %agg.result) {
-; CHECK-LABEL: test_mixed_7
+; X86-LABEL: test_mixed_7@@4
+; X64-LABEL: test_mixed_7@@8
; X64: mov{{[ql]}} %rcx, %rax
; CHECK: movaps %xmm{{[0-9]}}, 64(%{{rcx|eax}})
; CHECK: movaps %xmm{{[0-9]}}, 48(%{{rcx|eax}})
More information about the llvm-commits
mailing list