[NVPTX] Simplify and generalize constant printer.

This allows handling i128 values and fixes
https://bugs.llvm.org/show_bug.cgi?id=51789.

Differential Revision: https://reviews.llvm.org/D109458
This commit is contained in:
Artem Belevich 2021-08-27 11:18:11 -07:00
parent 367a9e709d
commit d99a83b4e5
3 changed files with 50 additions and 114 deletions

View File

@ -1748,135 +1748,63 @@ void NVPTXAsmPrinter::printScalarConstant(const Constant *CPV, raw_ostream &O) {
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,
AggBuffer *aggBuffer) {
AggBuffer *AggBuffer) {
const DataLayout &DL = getDataLayout();
int AllocSize = DL.getTypeAllocSize(CPV->getType());
if (isa<UndefValue>(CPV) || CPV->isNullValue()) {
int s = DL.getTypeAllocSize(CPV->getType());
if (s < Bytes)
s = Bytes;
aggBuffer->addZeros(s);
// Non-zero Bytes indicates that we need to zero-fill everything. Otherwise,
// only the space allocated by CPV.
AggBuffer->addZeros(Bytes ? Bytes : AllocSize);
return;
}
unsigned char ptr[8];
switch (CPV->getType()->getTypeID()) {
// Helper for filling AggBuffer with APInts.
auto AddIntToBuffer = [AggBuffer, Bytes](const APInt &Val) {
size_t NumBytes = (Val.getBitWidth() + 7) / 8;
SmallVector<unsigned char, 16> Buf(NumBytes);
for (unsigned I = 0; I < NumBytes; ++I) {
Buf[I] = Val.extractBitsAsZExtValue(8, I * 8);
}
AggBuffer->addBytes(Buf.data(), NumBytes, Bytes);
};
case Type::IntegerTyID: {
Type *ETy = CPV->getType();
if (ETy == Type::getInt8Ty(CPV->getContext())) {
unsigned char c = (unsigned char)cast<ConstantInt>(CPV)->getZExtValue();
ConvertIntToBytes<>(ptr, c);
aggBuffer->addBytes(ptr, 1, Bytes);
} else if (ETy == Type::getInt16Ty(CPV->getContext())) {
short int16 = (short)cast<ConstantInt>(CPV)->getZExtValue();
ConvertIntToBytes<>(ptr, int16);
aggBuffer->addBytes(ptr, 2, Bytes);
} else if (ETy == Type::getInt32Ty(CPV->getContext())) {
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
int int32 = (int)(constInt->getZExtValue());
ConvertIntToBytes<>(ptr, int32);
aggBuffer->addBytes(ptr, 4, Bytes);
switch (CPV->getType()->getTypeID()) {
case Type::IntegerTyID:
if (const auto CI = dyn_cast<ConstantInt>(CPV)) {
AddIntToBuffer(CI->getValue());
break;
}
if (const auto *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
if (const auto *CI =
dyn_cast<ConstantInt>(ConstantFoldConstant(Cexpr, DL))) {
AddIntToBuffer(CI->getValue());
break;
} else if (const auto *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
if (const auto *constInt = dyn_cast<ConstantInt>(
ConstantFoldConstant(Cexpr, DL))) {
int int32 = (int)(constInt->getZExtValue());
ConvertIntToBytes<>(ptr, int32);
aggBuffer->addBytes(ptr, 4, Bytes);
break;
}
if (Cexpr->getOpcode() == Instruction::PtrToInt) {
Value *v = Cexpr->getOperand(0)->stripPointerCasts();
aggBuffer->addSymbol(v, Cexpr->getOperand(0));
aggBuffer->addZeros(4);
break;
}
}
llvm_unreachable("unsupported integer const type");
} else if (ETy == Type::getInt64Ty(CPV->getContext())) {
if (const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
long long int64 = (long long)(constInt->getZExtValue());
ConvertIntToBytes<>(ptr, int64);
aggBuffer->addBytes(ptr, 8, Bytes);
if (Cexpr->getOpcode() == Instruction::PtrToInt) {
Value *V = Cexpr->getOperand(0)->stripPointerCasts();
AggBuffer->addSymbol(V, Cexpr->getOperand(0));
AggBuffer->addZeros(AllocSize);
break;
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
if (const auto *constInt = dyn_cast<ConstantInt>(
ConstantFoldConstant(Cexpr, DL))) {
long long int64 = (long long)(constInt->getZExtValue());
ConvertIntToBytes<>(ptr, int64);
aggBuffer->addBytes(ptr, 8, Bytes);
break;
}
if (Cexpr->getOpcode() == Instruction::PtrToInt) {
Value *v = Cexpr->getOperand(0)->stripPointerCasts();
aggBuffer->addSymbol(v, Cexpr->getOperand(0));
aggBuffer->addZeros(8);
break;
}
}
llvm_unreachable("unsupported integer const type");
} else
llvm_unreachable("unsupported integer const type");
}
llvm_unreachable("unsupported integer const type");
break;
}
case Type::HalfTyID:
case Type::FloatTyID:
case Type::DoubleTyID: {
const auto *CFP = cast<ConstantFP>(CPV);
Type *Ty = CFP->getType();
if (Ty == Type::getHalfTy(CPV->getContext())) {
APInt API = CFP->getValueAPF().bitcastToAPInt();
uint16_t float16 = API.getLoBits(16).getZExtValue();
ConvertIntToBytes<>(ptr, float16);
aggBuffer->addBytes(ptr, 2, Bytes);
} else if (Ty == Type::getFloatTy(CPV->getContext())) {
float float32 = (float) CFP->getValueAPF().convertToFloat();
ConvertFloatToBytes(ptr, float32);
aggBuffer->addBytes(ptr, 4, Bytes);
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
double float64 = CFP->getValueAPF().convertToDouble();
ConvertDoubleToBytes(ptr, float64);
aggBuffer->addBytes(ptr, 8, Bytes);
} else {
llvm_unreachable("unsupported fp const type");
}
case Type::DoubleTyID:
AddIntToBuffer(cast<ConstantFP>(CPV)->getValueAPF().bitcastToAPInt());
break;
}
case Type::PointerTyID: {
if (const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
aggBuffer->addSymbol(GVar, GVar);
AggBuffer->addSymbol(GVar, GVar);
} else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
const Value *v = Cexpr->stripPointerCasts();
aggBuffer->addSymbol(v, Cexpr);
AggBuffer->addSymbol(v, Cexpr);
}
unsigned int s = DL.getTypeAllocSize(CPV->getType());
aggBuffer->addZeros(s);
AggBuffer->addZeros(AllocSize);
break;
}
@ -1884,12 +1812,11 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes,
case Type::FixedVectorTyID:
case Type::StructTyID: {
if (isa<ConstantAggregate>(CPV) || isa<ConstantDataSequential>(CPV)) {
int ElementSize = DL.getTypeAllocSize(CPV->getType());
bufferAggregateConstant(CPV, aggBuffer);
if (Bytes > ElementSize)
aggBuffer->addZeros(Bytes - ElementSize);
bufferAggregateConstant(CPV, AggBuffer);
if (Bytes > AllocSize)
AggBuffer->addZeros(Bytes - AllocSize);
} else if (isa<ConstantAggregateZero>(CPV))
aggBuffer->addZeros(Bytes);
AggBuffer->addZeros(Bytes);
else
llvm_unreachable("Unexpected Constant type");
break;

View File

@ -106,6 +106,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
EmitGeneric = AP.EmitGeneric;
}
// Copy Num bytes from Ptr.
// if Bytes > Num, zero fill up to Bytes.
unsigned addBytes(unsigned char *Ptr, int Num, int Bytes) {
assert((curpos + Num) <= size);
assert((curpos + Bytes) <= size);

View File

@ -15,9 +15,16 @@
; 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 Gbli128[32] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
@Gbli128 = global [2 x i128] [i128 1339673755198158349044581307228491536, i128 21345817372864405881847059188222722561]
; 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]
; Make sure we fill in alignment gaps correctly.
; CHECK-DAG: .b8 GblU[12] = {7, 6, 0, 0, 5, 4, 3, 2, 1, 0, 0, 0};
@GblU = global {i16, i32, i8} {i16 1543, i32 33752069, i8 1}