forked from OSchip/llvm-project
Fix bitcast to address space cast for coerced load/stores
Coerced load/stores through memory do not take into account potential address space differences when it creates its bitcasts. Patch by David Salinas. Differential Revision: https://reviews.llvm.org/D53780 llvm-svn: 346413
This commit is contained in:
parent
778fba3188
commit
4bbdebc49a
|
@ -1253,8 +1253,8 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
|
|||
|
||||
// Otherwise do coercion through memory. This is stupid, but simple.
|
||||
Address Tmp = CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment());
|
||||
Address Casted = CGF.Builder.CreateBitCast(Tmp, CGF.AllocaInt8PtrTy);
|
||||
Address SrcCasted = CGF.Builder.CreateBitCast(Src, CGF.AllocaInt8PtrTy);
|
||||
Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty);
|
||||
Address SrcCasted = CGF.Builder.CreateElementBitCast(Src,CGF.Int8Ty);
|
||||
CGF.Builder.CreateMemCpy(Casted, SrcCasted,
|
||||
llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize),
|
||||
false);
|
||||
|
@ -1335,8 +1335,8 @@ static void CreateCoercedStore(llvm::Value *Src,
|
|||
// to that information.
|
||||
Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment());
|
||||
CGF.Builder.CreateStore(Src, Tmp);
|
||||
Address Casted = CGF.Builder.CreateBitCast(Tmp, CGF.AllocaInt8PtrTy);
|
||||
Address DstCasted = CGF.Builder.CreateBitCast(Dst, CGF.AllocaInt8PtrTy);
|
||||
Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty);
|
||||
Address DstCasted = CGF.Builder.CreateElementBitCast(Dst,CGF.Int8Ty);
|
||||
CGF.Builder.CreateMemCpy(DstCasted, Casted,
|
||||
llvm::ConstantInt::get(CGF.IntPtrTy, DstSize),
|
||||
false);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
|
||||
|
||||
template<typename T, unsigned int n> struct my_vector_base;
|
||||
|
||||
template<typename T>
|
||||
struct my_vector_base<T, 1> {
|
||||
typedef T Native_vec_ __attribute__((ext_vector_type(1)));
|
||||
|
||||
union {
|
||||
Native_vec_ data;
|
||||
struct {
|
||||
T x;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T, unsigned int rank>
|
||||
struct my_vector_type : public my_vector_base<T, rank> {
|
||||
using my_vector_base<T, rank>::data;
|
||||
using typename my_vector_base<T, rank>::Native_vec_;
|
||||
|
||||
template< typename U>
|
||||
my_vector_type(U x) noexcept
|
||||
{
|
||||
for (auto i = 0u; i != rank; ++i) data[i] = x;
|
||||
}
|
||||
my_vector_type& operator+=(const my_vector_type& x) noexcept
|
||||
{
|
||||
data += x.data;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, unsigned int n>
|
||||
inline
|
||||
my_vector_type<T, n> operator+(
|
||||
const my_vector_type<T, n>& x, const my_vector_type<T, n>& y) noexcept
|
||||
{
|
||||
return my_vector_type<T, n>{x} += y;
|
||||
}
|
||||
|
||||
using char1 = my_vector_type<char, 1>;
|
||||
|
||||
int mane() {
|
||||
|
||||
char1 f1{1};
|
||||
char1 f2{1};
|
||||
|
||||
// CHECK: %[[a:[^ ]+]] = addrspacecast i16 addrspace(5)* %{{[^ ]+}} to i16*
|
||||
// CHECK: %[[a:[^ ]+]] = addrspacecast %{{[^ ]+}} addrspace(5)* %{{[^ ]+}} to %{{[^ ]+}}
|
||||
|
||||
char1 f3 = f1 + f2;
|
||||
}
|
Loading…
Reference in New Issue