It's possible to have a constant expression who's size is quite big (e.g.,

i128). In that case, we may not be able to print out the MCExpr as an
expression. For instance, we could have an MCExpr like this:

    0xBEEF0000BEEF0000 | (0xBEEF0000BEEF0000 << 64)

The MCExpr printer handles sizes up to 64-bits, but this expression would
require 128-bits. In this situation, try to evaluate the constant expression and
emit that as the value into 64-bit chunks.
<rdar://problem/11070338>

llvm-svn: 153081
This commit is contained in:
Bill Wendling 2012-03-20 08:56:43 +00:00
parent 61aa773498
commit 338ddac8f7
2 changed files with 34 additions and 11 deletions

View File

@ -1847,13 +1847,12 @@ static void EmitGlobalConstantLargeInt(const ConstantInt *CI,
static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
AsmPrinter &AP) {
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
uint64_t Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
const TargetData *TD = AP.TM.getTargetData();
uint64_t Size = TD->getTypeAllocSize(CV->getType());
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
return AP.OutStreamer.EmitZeros(Size, AddrSpace);
}
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
switch (Size) {
case 1:
case 2:
@ -1874,7 +1873,6 @@ static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
return EmitGlobalConstantFP(CFP, AddrSpace, AP);
if (isa<ConstantPointerNull>(CV)) {
unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
return;
}
@ -1888,20 +1886,28 @@ static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
// Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
// vectors).
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
// Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
// vectors).
if (CE->getOpcode() == Instruction::BitCast)
return EmitGlobalConstantImpl(CE->getOperand(0), AddrSpace, AP);
if (Size > 8) {
// If the constant expression's size is greater than 64-bits, then we have
// to emit the value in chunks. Try to constant fold the value and emit it
// that way.
Constant *New = ConstantFoldConstantExpression(CE, TD);
if (New && New != CE)
return EmitGlobalConstantImpl(New, AddrSpace, AP);
}
}
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
return EmitGlobalConstantVector(V, AddrSpace, AP);
// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
// thread the streamer with EmitValue.
AP.OutStreamer.EmitValue(LowerConstant(CV, AP),
AP.TM.getTargetData()->getTypeAllocSize(CV->getType()),
AddrSpace);
AP.OutStreamer.EmitValue(LowerConstant(CV, AP), Size, AddrSpace);
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.

View File

@ -0,0 +1,17 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
; <rdar://problem/11070338>
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"
; CHECK: _.memset_pattern:
; CHECK-NEXT: .quad 4575657222473777152
; CHECK-NEXT: .quad 4575657222473777152
@.memset_pattern = internal unnamed_addr constant i128 or (i128 zext (i64 bitcast (<2 x float> <float 1.000000e+00, float 1.000000e+00> to i64) to i128), i128 shl (i128 zext (i64 bitcast (<2 x float> <float 1.000000e+00, float 1.000000e+00> to i64) to i128), i128 64)), align 16
define void @foo(i8* %a, i64 %b) {
call void @memset_pattern16(i8* %a, i8* bitcast (i128* @.memset_pattern to i8*), i64 %b)
ret void
}
declare void @memset_pattern16(i8*, i8*, i64)