1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[AsmPrinter] Make isRepeatedByteSequence smarter about odd integer types

- zext the value to alloc size first, then check if the value repeats
  with zero padding included. If so we can still emit a .space
- Do the checking with APInt.isSplat(8), which handles non-pow2 types
- Also handle large constants (bit width > 64)
- In a ConstantArray all elements have the same type, so it's sufficient
  to check the first constant recursively and then just compare if all
  following constants are the same by pointer compare

llvm-svn: 239977
This commit is contained in:
Benjamin Kramer 2015-06-17 23:55:17 +00:00
parent b946be2932
commit d3a7e1b8f1
2 changed files with 42 additions and 25 deletions

View File

@ -1795,40 +1795,30 @@ static int isRepeatedByteSequence(const ConstantDataSequential *V) {
/// composed of a repeated sequence of identical bytes and return the /// composed of a repeated sequence of identical bytes and return the
/// byte value. If it is not a repeated sequence, return -1. /// byte value. If it is not a repeated sequence, return -1.
static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
if (CI->getBitWidth() > 64) return -1; uint64_t Size = TM.getDataLayout()->getTypeAllocSizeInBits(V->getType());
assert(Size % 8 == 0);
uint64_t Size = // Extend the element to take zero padding into account.
TM.getDataLayout()->getTypeAllocSize(V->getType()); APInt Value = CI->getValue().zextOrSelf(Size);
uint64_t Value = CI->getZExtValue(); if (!Value.isSplat(8))
return -1;
// Make sure the constant is at least 8 bits long and has a power return Value.zextOrTrunc(8).getZExtValue();
// of 2 bit width. This guarantees the constant bit width is
// always a multiple of 8 bits, avoiding issues with padding out
// to Size and other such corner cases.
if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1;
uint8_t Byte = static_cast<uint8_t>(Value);
for (unsigned i = 1; i < Size; ++i) {
Value >>= 8;
if (static_cast<uint8_t>(Value) != Byte) return -1;
}
return Byte;
} }
if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) { if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) {
// Make sure all array elements are sequences of the same repeated // Make sure all array elements are sequences of the same repeated
// byte. // byte.
assert(CA->getNumOperands() != 0 && "Should be a CAZ"); assert(CA->getNumOperands() != 0 && "Should be a CAZ");
int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); Constant *Op0 = CA->getOperand(0);
if (Byte == -1) return -1; int Byte = isRepeatedByteSequence(Op0, TM);
if (Byte == -1)
return -1;
for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { // All array elements must be equal.
int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i)
if (ThisByte == -1) return -1; if (CA->getOperand(i) != Op0)
if (Byte != ThisByte) return -1; return -1;
}
return Byte; return Byte;
} }

View File

@ -0,0 +1,27 @@
; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s
@test1 = global [2 x i24] [i24 -1, i24 -1]
; CHECK-LABEL: test1:
; CHECK-NEXT: .long 16777215
; CHECK-NEXT: .long 16777215
@test2 = global [2 x i7] [i7 1, i7 1]
; CHECK-LABEL: test2:
; CHECK-NEXT: .space 2,1
@test3 = global [4 x i128] [i128 -1, i128 -1, i128 -1, i128 -1]
; CHECK-LABEL: test3:
; CHECK-NEXT: .space 64,255
@test4 = global [3 x i16] [i16 257, i16 257, i16 257]
; CHECK-LABEL: test4:
; CHECK-NEXT: .space 6,1
@test5 = global [2 x [2 x i16]] [[2 x i16] [i16 257, i16 257], [2 x i16] [i16 -1, i16 -1]]
; CHECK-LABEL: test5:
; CHECK-NEXT: .space 4,1
; CHECK-NEXT: .space 4,255
@test6 = global [2 x [2 x i16]] [[2 x i16] [i16 257, i16 257], [2 x i16] [i16 257, i16 257]]
; CHECK-LABEL: test6:
; CHECK-NEXT: .space 8,1