forked from OSchip/llvm-project
The constant initialization for globals in NVPTX is generated as an
array of bytes. The generation of this byte arrays was expecting the host to be little endian, which prevents big endian hosts to be used in the generation of the PTX code. This patch fixes the problem by changing the way the bytes are extracted so that it works for either little and big endian. llvm-svn: 239412
This commit is contained in:
parent
af79f3dbd3
commit
cd50135a29
|
@ -1760,6 +1760,30 @@ void NVPTXAsmPrinter::printScalarConstant(const Constant *CPV, raw_ostream &O) {
|
||||||
llvm_unreachable("Not scalar type found in printScalarConstant()");
|
llvm_unreachable("Not scalar type found in printScalarConstant()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These utility functions assure we get the right sequence of bytes for a given
|
||||||
|
// type even for big-endian machines
|
||||||
|
template <typename T> static void ConvertIntToBytes(unsigned char *p, T val) {
|
||||||
|
int64_t vp = (int64_t)val;
|
||||||
|
for (unsigned i = 0; i < sizeof(T); ++i) {
|
||||||
|
p[i] = (unsigned char)vp;
|
||||||
|
vp >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ConvertFloatToBytes(unsigned char *p, float val) {
|
||||||
|
int32_t *vp = (int32_t *)&val;
|
||||||
|
for (unsigned i = 0; i < sizeof(int32_t); ++i) {
|
||||||
|
p[i] = (unsigned char)*vp;
|
||||||
|
*vp >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ConvertDoubleToBytes(unsigned char *p, double val) {
|
||||||
|
int64_t *vp = (int64_t *)&val;
|
||||||
|
for (unsigned i = 0; i < sizeof(int64_t); ++i) {
|
||||||
|
p[i] = (unsigned char)*vp;
|
||||||
|
*vp >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
||||||
AggBuffer *aggBuffer) {
|
AggBuffer *aggBuffer) {
|
||||||
|
|
||||||
|
@ -1773,30 +1797,30 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *ptr;
|
unsigned char ptr[8];
|
||||||
switch (CPV->getType()->getTypeID()) {
|
switch (CPV->getType()->getTypeID()) {
|
||||||
|
|
||||||
case Type::IntegerTyID: {
|
case Type::IntegerTyID: {
|
||||||
const Type *ETy = CPV->getType();
|
const Type *ETy = CPV->getType();
|
||||||
if (ETy == Type::getInt8Ty(CPV->getContext())) {
|
if (ETy == Type::getInt8Ty(CPV->getContext())) {
|
||||||
unsigned char c = (unsigned char)cast<ConstantInt>(CPV)->getZExtValue();
|
unsigned char c = (unsigned char)cast<ConstantInt>(CPV)->getZExtValue();
|
||||||
ptr = &c;
|
ConvertIntToBytes<>(ptr, c);
|
||||||
aggBuffer->addBytes(ptr, 1, Bytes);
|
aggBuffer->addBytes(ptr, 1, Bytes);
|
||||||
} else if (ETy == Type::getInt16Ty(CPV->getContext())) {
|
} else if (ETy == Type::getInt16Ty(CPV->getContext())) {
|
||||||
short int16 = (short)cast<ConstantInt>(CPV)->getZExtValue();
|
short int16 = (short)cast<ConstantInt>(CPV)->getZExtValue();
|
||||||
ptr = (unsigned char *)&int16;
|
ConvertIntToBytes<>(ptr, int16);
|
||||||
aggBuffer->addBytes(ptr, 2, Bytes);
|
aggBuffer->addBytes(ptr, 2, Bytes);
|
||||||
} else if (ETy == Type::getInt32Ty(CPV->getContext())) {
|
} else if (ETy == Type::getInt32Ty(CPV->getContext())) {
|
||||||
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
|
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
|
||||||
int int32 = (int)(constInt->getZExtValue());
|
int int32 = (int)(constInt->getZExtValue());
|
||||||
ptr = (unsigned char *)&int32;
|
ConvertIntToBytes<>(ptr, int32);
|
||||||
aggBuffer->addBytes(ptr, 4, Bytes);
|
aggBuffer->addBytes(ptr, 4, Bytes);
|
||||||
break;
|
break;
|
||||||
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
|
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
|
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
|
||||||
ConstantFoldConstantExpression(Cexpr, *TD))) {
|
ConstantFoldConstantExpression(Cexpr, *TD))) {
|
||||||
int int32 = (int)(constInt->getZExtValue());
|
int int32 = (int)(constInt->getZExtValue());
|
||||||
ptr = (unsigned char *)&int32;
|
ConvertIntToBytes<>(ptr, int32);
|
||||||
aggBuffer->addBytes(ptr, 4, Bytes);
|
aggBuffer->addBytes(ptr, 4, Bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1811,14 +1835,14 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
||||||
} else if (ETy == Type::getInt64Ty(CPV->getContext())) {
|
} else if (ETy == Type::getInt64Ty(CPV->getContext())) {
|
||||||
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
|
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
|
||||||
long long int64 = (long long)(constInt->getZExtValue());
|
long long int64 = (long long)(constInt->getZExtValue());
|
||||||
ptr = (unsigned char *)&int64;
|
ConvertIntToBytes<>(ptr, int64);
|
||||||
aggBuffer->addBytes(ptr, 8, Bytes);
|
aggBuffer->addBytes(ptr, 8, Bytes);
|
||||||
break;
|
break;
|
||||||
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
|
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
|
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(
|
||||||
ConstantFoldConstantExpression(Cexpr, *TD))) {
|
ConstantFoldConstantExpression(Cexpr, *TD))) {
|
||||||
long long int64 = (long long)(constInt->getZExtValue());
|
long long int64 = (long long)(constInt->getZExtValue());
|
||||||
ptr = (unsigned char *)&int64;
|
ConvertIntToBytes<>(ptr, int64);
|
||||||
aggBuffer->addBytes(ptr, 8, Bytes);
|
aggBuffer->addBytes(ptr, 8, Bytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1840,11 +1864,11 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
|
||||||
const Type *Ty = CFP->getType();
|
const Type *Ty = CFP->getType();
|
||||||
if (Ty == Type::getFloatTy(CPV->getContext())) {
|
if (Ty == Type::getFloatTy(CPV->getContext())) {
|
||||||
float float32 = (float) CFP->getValueAPF().convertToFloat();
|
float float32 = (float) CFP->getValueAPF().convertToFloat();
|
||||||
ptr = (unsigned char *)&float32;
|
ConvertFloatToBytes(ptr, float32);
|
||||||
aggBuffer->addBytes(ptr, 4, Bytes);
|
aggBuffer->addBytes(ptr, 4, Bytes);
|
||||||
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
|
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
|
||||||
double float64 = CFP->getValueAPF().convertToDouble();
|
double float64 = CFP->getValueAPF().convertToDouble();
|
||||||
ptr = (unsigned char *)&float64;
|
ConvertDoubleToBytes(ptr, float64);
|
||||||
aggBuffer->addBytes(ptr, 8, Bytes);
|
aggBuffer->addBytes(ptr, 8, Bytes);
|
||||||
} else {
|
} else {
|
||||||
llvm_unreachable("unsupported fp const type");
|
llvm_unreachable("unsupported fp const type");
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s
|
||||||
|
|
||||||
|
; Make sure the globals constant initializers are not prone to host endianess
|
||||||
|
; issues.
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gbli08[2] = {171, 205};
|
||||||
|
@Gbli08 = global [2 x i8] [i8 171, i8 205]
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gbli16[4] = {205, 171, 1, 239};
|
||||||
|
@Gbli16 = global [2 x i16] [i16 43981, i16 61185]
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gbli32[8] = {1, 239, 205, 171, 137, 103, 69, 35};
|
||||||
|
@Gbli32 = global [2 x i32] [i32 2882400001, i32 591751049]
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gbli64[16] = {137, 103, 69, 35, 1, 239, 205, 171, 239, 205, 171, 137, 103, 69, 35, 1};
|
||||||
|
@Gbli64 = global [2 x i64] [i64 12379813738877118345, i64 81985529216486895]
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gblf32[8] = {192, 225, 100, 75, 0, 96, 106, 69};
|
||||||
|
@Gblf32 = global [2 x float] [float 1.5e+7, float 3.75e+3]
|
||||||
|
|
||||||
|
; CHECK-DAG: .b8 Gblf64[16] = {116, 10, 181, 48, 134, 62, 230, 58, 106, 222, 138, 98, 204, 250, 200, 75};
|
||||||
|
@Gblf64 = global [2 x double] [double 5.75e-25, double 12.25e+56]
|
||||||
|
|
Loading…
Reference in New Issue