mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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:
parent
61aa773498
commit
338ddac8f7
@ -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.
|
||||
|
17
test/CodeGen/X86/2012-03-20-LargeConstantExpr.ll
Normal file
17
test/CodeGen/X86/2012-03-20-LargeConstantExpr.ll
Normal 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)
|
Loading…
Reference in New Issue
Block a user