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:
Yaxun Liu 2018-11-08 16:55:46 +00:00
parent 778fba3188
commit 4bbdebc49a
2 changed files with 57 additions and 4 deletions

View File

@ -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);

View File

@ -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;
}