forked from OSchip/llvm-project
[WebAssembly] Enable folding of offsets into global variable addresses.
llvm-svn: 254882
This commit is contained in:
parent
6ddce716cb
commit
a4b710a74f
|
@ -196,9 +196,8 @@ FastISel *WebAssemblyTargetLowering::createFastISel(
|
|||
|
||||
bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
|
||||
const GlobalAddressSDNode * /*GA*/) const {
|
||||
// The WebAssembly target doesn't support folding offsets into global
|
||||
// addresses.
|
||||
return false;
|
||||
// All offsets can be folded.
|
||||
return true;
|
||||
}
|
||||
|
||||
MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
|
||||
|
@ -528,13 +527,12 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
|
|||
SDLoc DL(Op);
|
||||
const auto *GA = cast<GlobalAddressSDNode>(Op);
|
||||
EVT VT = Op.getValueType();
|
||||
assert(GA->getOffset() == 0 &&
|
||||
"offsets on global addresses are forbidden by isOffsetFoldingLegal");
|
||||
assert(GA->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
|
||||
if (GA->getAddressSpace() != 0)
|
||||
fail(DL, DAG, "WebAssembly only expects the 0 address space");
|
||||
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
|
||||
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT));
|
||||
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
|
||||
GA->getOffset()));
|
||||
}
|
||||
|
||||
SDValue
|
||||
|
|
|
@ -39,11 +39,16 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
|
|||
|
||||
MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
|
||||
MCSymbol *Sym) const {
|
||||
assert(MO.getTargetFlags() == 0 && "WebAssembly does not use target flags");
|
||||
|
||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
|
||||
|
||||
if (!MO.isJTI() && MO.getOffset())
|
||||
llvm_unreachable("unknown symbol op");
|
||||
int64_t Offset = MO.getOffset();
|
||||
if (Offset != 0) {
|
||||
assert(!MO.isJTI() && "Unexpected offset with jump table index");
|
||||
Expr =
|
||||
MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx);
|
||||
}
|
||||
|
||||
return MCOperand::createExpr(Expr);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||
|
||||
; Test that constant offsets can be folded into global addresses.
|
||||
|
||||
target datalayout = "e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown"
|
||||
|
||||
@x = external global [0 x i32]
|
||||
@y = global [50 x i32] zeroinitializer
|
||||
|
||||
; Test basic constant offsets of both defined and external symbols.
|
||||
|
||||
; CHECK-LABEL: test0:
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; CHECK-NEXT: i32.const $push0=, x+188{{$}}
|
||||
; CHECK=NEXT: return $pop0{{$}}
|
||||
define i32* @test0() {
|
||||
ret i32* getelementptr ([0 x i32], [0 x i32]* @x, i32 0, i32 47)
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test1:
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; CHECK-NEXT: i32.const $push0=, y+188{{$}}
|
||||
; CHECK=NEXT: return $pop0{{$}}
|
||||
define i32* @test1() {
|
||||
ret i32* getelementptr ([50 x i32], [50 x i32]* @y, i32 0, i32 47)
|
||||
}
|
||||
|
||||
; Test zero offsets.
|
||||
|
||||
; CHECK-LABEL: test2:
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; CHECK-NEXT: i32.const $push0=, x{{$}}
|
||||
; CHECK=NEXT: return $pop0{{$}}
|
||||
define i32* @test2() {
|
||||
ret i32* getelementptr ([0 x i32], [0 x i32]* @x, i32 0, i32 0)
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test3:
|
||||
; CHECK-NEXT: .result i32{{$}}
|
||||
; CHECK-NEXT: i32.const $push0=, y{{$}}
|
||||
; CHECK=NEXT: return $pop0{{$}}
|
||||
define i32* @test3() {
|
||||
ret i32* getelementptr ([50 x i32], [50 x i32]* @y, i32 0, i32 0)
|
||||
}
|
Loading…
Reference in New Issue