[WebAssembly] Remove the output operand from stores.

Per spec changes, store instructions in WebAssembly no longer have a return
value. Update the instruction descriptions.

Differential Revision: https://reviews.llvm.org/D25122

llvm-svn: 283501
This commit is contained in:
Dan Gohman 2016-10-06 22:08:28 +00:00
parent e51bede1d8
commit 7f1bdb2e02
22 changed files with 203 additions and 227 deletions

View File

@ -134,9 +134,12 @@ inline unsigned GetDefaultP2Align(unsigned Opcode) {
}
/// The operand number of the load or store address in load/store instructions.
static const unsigned MemOpAddressOperandNo = 2;
/// The operand number of the stored value in a store instruction.
static const unsigned StoreValueOperandNo = 4;
static const unsigned LoadAddressOperandNo = 2;
static const unsigned StoreAddressOperandNo = 1;
/// The operand number of the load or store p2align in load/store instructions.
static const unsigned LoadP2AlignOperandNo = 3;
static const unsigned StoreP2AlignOperandNo = 2;
} // end namespace WebAssembly
} // end namespace llvm

View File

@ -1092,34 +1092,27 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) {
return false;
unsigned Opc;
const TargetRegisterClass *RC;
bool VTIsi1 = false;
switch (getSimpleType(Store->getValueOperand()->getType())) {
case MVT::i1:
VTIsi1 = true;
case MVT::i8:
Opc = WebAssembly::STORE8_I32;
RC = &WebAssembly::I32RegClass;
break;
case MVT::i16:
Opc = WebAssembly::STORE16_I32;
RC = &WebAssembly::I32RegClass;
break;
case MVT::i32:
Opc = WebAssembly::STORE_I32;
RC = &WebAssembly::I32RegClass;
break;
case MVT::i64:
Opc = WebAssembly::STORE_I64;
RC = &WebAssembly::I64RegClass;
break;
case MVT::f32:
Opc = WebAssembly::STORE_F32;
RC = &WebAssembly::F32RegClass;
break;
case MVT::f64:
Opc = WebAssembly::STORE_F64;
RC = &WebAssembly::F64RegClass;
break;
default: return false;
}
@ -1132,9 +1125,7 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) {
if (VTIsi1)
ValueReg = maskI1Value(ValueReg, Store->getValueOperand());
unsigned ResultReg = createResultReg(RC);
auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
ResultReg);
auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Store));

View File

@ -88,7 +88,6 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
const TargetRegisterClass *PtrRC =
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
unsigned Zero = MRI.createVirtualRegister(PtrRC);
unsigned Drop = MRI.createVirtualRegister(PtrRC);
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
@ -96,7 +95,7 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
MachineMemOperand *MMO = MF.getMachineMemOperand(
MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
MachineMemOperand::MOStore, 4, 4);
BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32), Drop)
BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32))
.addExternalSymbol(SPSymbol)
.addReg(Zero)
.addImm(2) // p2align

View File

@ -446,23 +446,19 @@ def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
let Defs = [ARGUMENTS] in {
// Basic store.
// Note that we split the patterns out of the instruction definitions because
// WebAssembly's stores return their operand value, and tablegen doesn't like
// instruction definition patterns that don't reference all of the output
// operands.
// Note: WebAssembly inverts SelectionDAG's usual operand order.
def STORE_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x33>;
def STORE_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x34>;
def STORE_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, F32:$val), [],
"f32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x35>;
def STORE_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, F64:$val), [],
"f64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x36>;
def STORE_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store\t${off}(${addr})${p2align}, $val", 0x33>;
def STORE_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store\t${off}(${addr})${p2align}, $val", 0x34>;
def STORE_F32 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, F32:$val), [],
"f32.store\t${off}(${addr})${p2align}, $val", 0x35>;
def STORE_F64 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, F64:$val), [],
"f64.store\t${off}(${addr})${p2align}, $val", 0x36>;
} // Defs = [ARGUMENTS]
@ -543,21 +539,21 @@ def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
let Defs = [ARGUMENTS] in {
// Truncating store.
def STORE8_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x2e>;
def STORE16_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x2f>;
def STORE8_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x30>;
def STORE16_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x31>;
def STORE32_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store32\t$dst, ${off}(${addr})${p2align}, $val", 0x32>;
def STORE8_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store8\t${off}(${addr})${p2align}, $val", 0x2e>;
def STORE16_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I32:$val), [],
"i32.store16\t${off}(${addr})${p2align}, $val", 0x2f>;
def STORE8_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store8\t${off}(${addr})${p2align}, $val", 0x30>;
def STORE16_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store16\t${off}(${addr})${p2align}, $val", 0x31>;
def STORE32_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
P2Align:$p2align, I64:$val), [],
"i64.store32\t${off}(${addr})${p2align}, $val", 0x32>;
} // Defs = [ARGUMENTS]

View File

@ -119,25 +119,6 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
switch (MI.getOpcode()) {
default:
break;
case WebAssembly::STORE8_I32:
case WebAssembly::STORE16_I32:
case WebAssembly::STORE8_I64:
case WebAssembly::STORE16_I64:
case WebAssembly::STORE32_I64:
case WebAssembly::STORE_F32:
case WebAssembly::STORE_F64:
case WebAssembly::STORE_I32:
case WebAssembly::STORE_I64: {
// Store instructions return their value operand. If we ended up using
// the same register for both, replace it with a dead def so that it
// can use $drop instead.
MachineOperand &MO = MI.getOperand(0);
unsigned OldReg = MO.getReg();
unsigned NewReg =
MI.getOperand(WebAssembly::StoreValueOperandNo).getReg();
Changed |= MaybeRewriteToDrop(OldReg, NewReg, MO, MFI, MRI);
break;
}
case WebAssembly::CALL_I32:
case WebAssembly::CALL_I64: {
MachineOperand &Op1 = MI.getOperand(1);

View File

@ -71,9 +71,10 @@ void WebAssemblyRegisterInfo::eliminateFrameIndex(
// If this is the address operand of a load or store, make it relative to SP
// and fold the frame offset directly in.
if (MI.mayLoadOrStore() && FIOperandNum == WebAssembly::MemOpAddressOperandNo) {
assert(FrameOffset >= 0 && MI.getOperand(1).getImm() >= 0);
int64_t Offset = MI.getOperand(1).getImm() + FrameOffset;
if ((MI.mayLoad() && FIOperandNum == WebAssembly::LoadAddressOperandNo) ||
(MI.mayStore() && FIOperandNum == WebAssembly::StoreAddressOperandNo)) {
assert(FrameOffset >= 0 && MI.getOperand(FIOperandNum - 1).getImm() >= 0);
int64_t Offset = MI.getOperand(FIOperandNum - 1).getImm() + FrameOffset;
if (static_cast<uint64_t>(Offset) <= std::numeric_limits<uint32_t>::max()) {
MI.getOperand(FIOperandNum - 1).setImm(Offset);

View File

@ -50,6 +50,27 @@ FunctionPass *llvm::createWebAssemblySetP2AlignOperands() {
return new WebAssemblySetP2AlignOperands();
}
static void RewriteP2Align(MachineInstr &MI, unsigned OperandNo) {
assert(MI.getOperand(OperandNo).getImm() == 0 &&
"ISel should set p2align operands to 0");
assert(MI.hasOneMemOperand() &&
"Load and store instructions have exactly one mem operand");
assert((*MI.memoperands_begin())->getSize() ==
(UINT64_C(1)
<< WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
"Default p2align value should be natural");
assert(MI.getDesc().OpInfo[OperandNo].OperandType ==
WebAssembly::OPERAND_P2ALIGN &&
"Load and store instructions should have a p2align operand");
uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
// WebAssembly does not currently support supernatural alignment.
P2Align = std::min(
P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
MI.getOperand(OperandNo).setImm(P2Align);
}
bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
DEBUG({
dbgs() << "********** Set p2align Operands **********\n"
@ -75,6 +96,8 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
case WebAssembly::LOAD16_U_I64:
case WebAssembly::LOAD32_S_I64:
case WebAssembly::LOAD32_U_I64:
RewriteP2Align(MI, WebAssembly::LoadP2AlignOperandNo);
break;
case WebAssembly::STORE_I32:
case WebAssembly::STORE_I64:
case WebAssembly::STORE_F32:
@ -83,27 +106,9 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
case WebAssembly::STORE16_I32:
case WebAssembly::STORE8_I64:
case WebAssembly::STORE16_I64:
case WebAssembly::STORE32_I64: {
assert(MI.getOperand(3).getImm() == 0 &&
"ISel should set p2align operands to 0");
assert(MI.hasOneMemOperand() &&
"Load and store instructions have exactly one mem operand");
assert((*MI.memoperands_begin())->getSize() ==
(UINT64_C(1)
<< WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
"Default p2align value should be natural");
assert(MI.getDesc().OpInfo[3].OperandType ==
WebAssembly::OPERAND_P2ALIGN &&
"Load and store instructions should have a p2align operand");
uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
// WebAssembly does not currently support supernatural alignment.
P2Align = std::min(
P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
MI.getOperand(3).setImm(P2Align);
case WebAssembly::STORE32_I64:
RewriteP2Align(MI, WebAssembly::StoreP2AlignOperandNo);
break;
}
default:
break;
}

View File

@ -357,7 +357,7 @@ define i32 @load_test21(i32* %p, i32 %n) {
; CHECK-LABEL: store_test0:
; CHECK-NEXT: param i32{{$}}
; CHECK-NEXT: i32.const $push0=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, g+40($pop0), $0{{$}}
; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test0(i32 %i) {
store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
@ -367,7 +367,7 @@ define void @store_test0(i32 %i) {
; CHECK-LABEL: store_test0_noinbounds:
; CHECK-NEXT: param i32{{$}}
; CHECK-NEXT: i32.const $push0=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, g+40($pop0), $0{{$}}
; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test0_noinbounds(i32 %i) {
store i32 %i, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
@ -378,7 +378,7 @@ define void @store_test0_noinbounds(i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test1(i32 %n, i32 %i) {
%add = add nsw i32 %n, 10
@ -391,7 +391,7 @@ define void @store_test1(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test2(i32 %n, i32 %i) {
%add = add nsw i32 10, %n
@ -404,7 +404,7 @@ define void @store_test2(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test3(i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
@ -417,7 +417,7 @@ define void @store_test3(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test4(i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
@ -429,7 +429,7 @@ define void @store_test4(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test5(i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
@ -441,7 +441,7 @@ define void @store_test5(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test6(i32 %n, i32 %i) {
%add = add nsw i32 %n, 10
@ -454,7 +454,7 @@ define void @store_test6(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test7(i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
@ -467,7 +467,7 @@ define void @store_test7(i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEX T: i32.store $drop=, g+40($pop1), $1{{$}}
; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
; CHECK-NEX T: return{{$}}
define void @store_test8(i32 %n, i32 %i) {
%add = add nsw i32 10, %n
@ -479,7 +479,7 @@ define void @store_test8(i32 %n, i32 %i) {
; CHECK-LABEL: store_test9:
; CHECK-NEXT: param i32{{$}}
; CHECK-NEXT: i32.const $push0=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, g-40($pop0), $0{{$}}
; CHECK-NEXT: i32.store g-40($pop0), $0{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test9(i32 %i) {
store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
@ -492,7 +492,7 @@ define void @store_test9(i32 %i) {
; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
; CHECK-NEXT: i32.const $push2=, g-40{{$}}
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop3), $1{{$}}
; CHECK-NEXT: i32.store 0($pop3), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test10(i32 %n, i32 %i) {
%add = add nsw i32 %n, -10
@ -503,7 +503,7 @@ define void @store_test10(i32 %n, i32 %i) {
; CHECK-LABEL: store_test11:
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 40($0), $1{{$}}
; CHECK-NEXT: i32.store 40($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test11(i32* %p, i32 %i) {
%arrayidx = getelementptr inbounds i32, i32* %p, i32 10
@ -515,7 +515,7 @@ define void @store_test11(i32* %p, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, 40{{$}}
; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop1), $1{{$}}
; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test11_noinbounds(i32* %p, i32 %i) {
%arrayidx = getelementptr i32, i32* %p, i32 10
@ -530,7 +530,7 @@ define void @store_test11_noinbounds(i32* %p, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test12(i32* %p, i32 %n, i32 %i) {
%add = add nsw i32 %n, 10
@ -546,7 +546,7 @@ define void @store_test12(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test13(i32* %p, i32 %n, i32 %i) {
%add = add nsw i32 10, %n
@ -560,7 +560,7 @@ define void @store_test13(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}}
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.store $drop=, 40($pop2), $2{{$}}
; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test14(i32* %p, i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
@ -576,7 +576,7 @@ define void @store_test14(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test15(i32* %p, i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* %p, i32 10
@ -592,7 +592,7 @@ define void @store_test15(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test16(i32* %p, i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* %p, i32 10
@ -608,7 +608,7 @@ define void @store_test16(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test17(i32* %p, i32 %n, i32 %i) {
%add = add nsw i32 %n, 10
@ -622,7 +622,7 @@ define void @store_test17(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.const $push0=, 2{{$}}
; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}}
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.store $drop=, 40($pop2), $2{{$}}
; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test18(i32* %p, i32 %n, i32 %i) {
%add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
@ -638,7 +638,7 @@ define void @store_test18(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, 40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test19(i32* %p, i32 %n, i32 %i) {
%add = add nsw i32 10, %n
@ -651,7 +651,7 @@ define void @store_test19(i32* %p, i32 %n, i32 %i) {
; CHECK-NEXT: param i32, i32{{$}}
; CHECK-NEXT: i32.const $push0=, -40{{$}}
; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop1), $1{{$}}
; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test20(i32* %p, i32 %i) {
%arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
@ -666,7 +666,7 @@ define void @store_test20(i32* %p, i32 %i) {
; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
; CHECK-NEXT: i32.const $push3=, -40{{$}}
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop4), $2{{$}}
; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
; CHECK-NEXT: return{{$}}
define void @store_test21(i32* %p, i32 %n, i32 %i) {
%add = add nsw i32 %n, -10

View File

@ -31,10 +31,10 @@ define void @byval_arg(%SmallStruct* %ptr) {
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
; Ensure SP is stored back before the call
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; Copy the SmallStruct argument to the stack (SP+12, original SP-4)
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
; CHECK-NEXT: i32.store $drop=, 12($[[SP]]), $pop[[L0]]
; CHECK-NEXT: i32.store 12($[[SP]]), $pop[[L0]]
; Pass a pointer to the stack slot to the function
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 12{{$}}
; CHECK-NEXT: i32.add $push[[ARG:.+]]=, $[[SP]], $pop[[L5]]{{$}}
@ -44,7 +44,7 @@ define void @byval_arg(%SmallStruct* %ptr) {
; CHECK-NEXT: i32.const $push[[L7:.+]]=, 0
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L6]]
; CHECK-NEXT: i32.store {{.*}}=, __stack_pointer($pop[[L7]]), $pop[[L8]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L7]]), $pop[[L8]]
; CHECK-NEXT: return
ret void
}
@ -56,10 +56,10 @@ define void @byval_arg_align8(%SmallStruct* %ptr) {
; CHECK: i32.const $push[[L1:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}}
; Copy the SmallStruct argument to the stack (SP+8, original SP-8)
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}}
; CHECK-NEXT: i32.store $drop=, 8($[[SP]]), $pop[[L0]]{{$}}
; CHECK-NEXT: i32.store 8($[[SP]]), $pop[[L0]]{{$}}
; Pass a pointer to the stack slot to the function
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 8{{$}}
; CHECK-NEXT: i32.add $push[[ARG:.+]]=, $[[SP]], $pop[[L5]]{{$}}
@ -75,11 +75,11 @@ define void @byval_arg_double(%AlignedStruct* %ptr) {
; CHECK: i32.const $push[[L1:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L14:.+]]=, {{.+}}, $pop[[L1]]
; CHECK-NEXT: tee_local $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]]
; CHECK-NEXT: i32.store $drop=, {{.+}}, $pop[[L13]]
; CHECK-NEXT: i32.store {{.+}}, $pop[[L13]]
; Copy the AlignedStruct argument to the stack (SP+0, original SP-16)
; Just check the last load/store pair of the memcpy
; CHECK: i64.load $push[[L4:.+]]=, 0($0)
; CHECK-NEXT: i64.store $drop=, 0($[[SP]]), $pop[[L4]]
; CHECK-NEXT: i64.store 0($[[SP]]), $pop[[L4]]
; Pass a pointer to the stack slot to the function
; CHECK-NEXT: call ext_byval_func_alignedstruct@FUNCTION, $[[SP]]
tail call void @ext_byval_func_alignedstruct(%AlignedStruct* byval %ptr)
@ -119,7 +119,7 @@ define void @byval_empty_callee(%EmptyStruct* byval %ptr) {
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072
; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $[[SP]], ${{.+}}, $pop{{.+}}
; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}

View File

@ -275,13 +275,13 @@ entry:
; CHECK-LABEL: minimal_loop:
; CHECK-NOT: br
; CHECK: .LBB7_1:
; CHECK: i32.store $drop=, 0($0), $pop{{[0-9]+}}{{$}}
; CHECK: i32.store 0($0), $pop{{[0-9]+}}{{$}}
; CHECK: br 0{{$}}
; CHECK: .LBB7_2:
; OPT-LABEL: minimal_loop:
; OPT-NOT: br
; OPT: .LBB7_1:
; OPT: i32.store $drop=, 0($0), $pop{{[0-9]+}}{{$}}
; OPT: i32.store 0($0), $pop{{[0-9]+}}{{$}}
; OPT: br 0{{$}}
; OPT: .LBB7_2:
define void @minimal_loop(i32* %p) {

View File

@ -25,7 +25,7 @@ b:
; CHECK: i32.const $push1=, 0
; CHECK: i32.const $push2=, 0
; CHECK: i32.store $drop=, 0($pop1), $pop2
; CHECK: i32.store 0($pop1), $pop2
define hidden i32 @c() #0 {
entry:
store i32 zext (i1 icmp eq (void (...)* inttoptr (i32 10 to void (...)*), void (...)* null) to i32), i32* inttoptr (i32 0 to i32 *)

View File

@ -117,7 +117,7 @@ define i16 @ldi16_a4(i16 *%p) {
; CHECK-LABEL: sti32_a1:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: i32.store 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a1(i32 *%p, i32 %v) {
store i32 %v, i32* %p, align 1
@ -126,7 +126,7 @@ define void @sti32_a1(i32 *%p, i32 %v) {
; CHECK-LABEL: sti32_a2:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: i32.store 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a2(i32 *%p, i32 %v) {
store i32 %v, i32* %p, align 2
@ -137,7 +137,7 @@ define void @sti32_a2(i32 *%p, i32 %v) {
; CHECK-LABEL: sti32_a4:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a4(i32 *%p, i32 %v) {
store i32 %v, i32* %p, align 4
@ -148,7 +148,7 @@ define void @sti32_a4(i32 *%p, i32 %v) {
; CHECK-LABEL: sti32:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32(i32 *%p, i32 %v) {
store i32 %v, i32* %p
@ -157,7 +157,7 @@ define void @sti32(i32 *%p, i32 %v) {
; CHECK-LABEL: sti32_a8:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a8(i32 *%p, i32 %v) {
store i32 %v, i32* %p, align 8
@ -168,7 +168,7 @@ define void @sti32_a8(i32 *%p, i32 %v) {
; CHECK-LABEL: sti8_a1:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store8 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store8 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti8_a1(i8 *%p, i8 %v) {
store i8 %v, i8* %p, align 1
@ -177,7 +177,7 @@ define void @sti8_a1(i8 *%p, i8 %v) {
; CHECK-LABEL: sti8_a2:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store8 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store8 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti8_a2(i8 *%p, i8 %v) {
store i8 %v, i8* %p, align 2
@ -186,7 +186,7 @@ define void @sti8_a2(i8 *%p, i8 %v) {
; CHECK-LABEL: sti16_a1:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store16 $drop=, 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: i32.store16 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a1(i16 *%p, i16 %v) {
store i16 %v, i16* %p, align 1
@ -195,7 +195,7 @@ define void @sti16_a1(i16 *%p, i16 %v) {
; CHECK-LABEL: sti16_a2:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store16 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store16 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a2(i16 *%p, i16 %v) {
store i16 %v, i16* %p, align 2
@ -204,7 +204,7 @@ define void @sti16_a2(i16 *%p, i16 %v) {
; CHECK-LABEL: sti16_a4:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store16 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store16 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a4(i16 *%p, i16 %v) {
store i16 %v, i16* %p, align 4

View File

@ -176,7 +176,7 @@ define i64 @ldi32_a8(i32 *%p) {
; CHECK-LABEL: sti64_a1:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: i64.store 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64_a1(i64 *%p, i64 %v) {
store i64 %v, i64* %p, align 1
@ -185,7 +185,7 @@ define void @sti64_a1(i64 *%p, i64 %v) {
; CHECK-LABEL: sti64_a2:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: i64.store 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64_a2(i64 *%p, i64 %v) {
store i64 %v, i64* %p, align 2
@ -194,7 +194,7 @@ define void @sti64_a2(i64 *%p, i64 %v) {
; CHECK-LABEL: sti64_a4:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0):p2align=2, $1{{$}}
; CHECK-NEXT: i64.store 0($0):p2align=2, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64_a4(i64 *%p, i64 %v) {
store i64 %v, i64* %p, align 4
@ -205,7 +205,7 @@ define void @sti64_a4(i64 *%p, i64 %v) {
; CHECK-LABEL: sti64_a8:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64_a8(i64 *%p, i64 %v) {
store i64 %v, i64* %p, align 8
@ -216,7 +216,7 @@ define void @sti64_a8(i64 *%p, i64 %v) {
; CHECK-LABEL: sti64:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64(i64 *%p, i64 %v) {
store i64 %v, i64* %p
@ -225,7 +225,7 @@ define void @sti64(i64 *%p, i64 %v) {
; CHECK-LABEL: sti64_a16:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64_a16(i64 *%p, i64 %v) {
store i64 %v, i64* %p, align 16
@ -236,7 +236,7 @@ define void @sti64_a16(i64 *%p, i64 %v) {
; CHECK-LABEL: sti8_a1:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store8 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store8 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti8_a1(i8 *%p, i64 %w) {
%v = trunc i64 %w to i8
@ -246,7 +246,7 @@ define void @sti8_a1(i8 *%p, i64 %w) {
; CHECK-LABEL: sti8_a2:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store8 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store8 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti8_a2(i8 *%p, i64 %w) {
%v = trunc i64 %w to i8
@ -256,7 +256,7 @@ define void @sti8_a2(i8 *%p, i64 %w) {
; CHECK-LABEL: sti16_a1:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store16 $drop=, 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: i64.store16 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a1(i16 *%p, i64 %w) {
%v = trunc i64 %w to i16
@ -266,7 +266,7 @@ define void @sti16_a1(i16 *%p, i64 %w) {
; CHECK-LABEL: sti16_a2:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store16 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store16 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a2(i16 *%p, i64 %w) {
%v = trunc i64 %w to i16
@ -276,7 +276,7 @@ define void @sti16_a2(i16 *%p, i64 %w) {
; CHECK-LABEL: sti16_a4:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store16 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store16 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti16_a4(i16 *%p, i64 %w) {
%v = trunc i64 %w to i16
@ -286,7 +286,7 @@ define void @sti16_a4(i16 *%p, i64 %w) {
; CHECK-LABEL: sti32_a1:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store32 $drop=, 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: i64.store32 0($0):p2align=0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a1(i32 *%p, i64 %w) {
%v = trunc i64 %w to i32
@ -296,7 +296,7 @@ define void @sti32_a1(i32 *%p, i64 %w) {
; CHECK-LABEL: sti32_a2:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store32 $drop=, 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: i64.store32 0($0):p2align=1, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a2(i32 *%p, i64 %w) {
%v = trunc i64 %w to i32
@ -306,7 +306,7 @@ define void @sti32_a2(i32 *%p, i64 %w) {
; CHECK-LABEL: sti32_a4:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store32 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store32 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a4(i32 *%p, i64 %w) {
%v = trunc i64 %w to i32
@ -316,7 +316,7 @@ define void @sti32_a4(i32 *%p, i64 %w) {
; CHECK-LABEL: sti32_a8:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store32 $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store32 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32_a8(i32 *%p, i64 %w) {
%v = trunc i64 %w to i32

View File

@ -59,7 +59,7 @@ entry:
; CHECK-LABEL: X_i16:
; CHECK: foo $1{{$}}
; CHECK: i32.store16 $drop=, 0($0), $1{{$}}
; CHECK: i32.store16 0($0), $1{{$}}
define void @X_i16(i16 * %t) {
call void asm sideeffect "foo $0", "=*X,~{dirflag},~{fpsr},~{flags},~{memory}"(i16* %t)
ret void
@ -67,7 +67,7 @@ define void @X_i16(i16 * %t) {
; CHECK-LABEL: X_ptr:
; CHECK: foo $1{{$}}
; CHECK: i32.store $drop=, 0($0), $1{{$}}
; CHECK: i32.store 0($0), $1{{$}}
define void @X_ptr(i16 ** %t) {
call void asm sideeffect "foo $0", "=*X,~{dirflag},~{fpsr},~{flags},~{memory}"(i16** %t)
ret void

View File

@ -52,7 +52,7 @@ define i64 @load_s_i1_i64(i1* %p) {
; CHECK-LABEL: store_i32_i1:
; CHECK: i32.const $push[[NUM0:[0-9]+]]=, 1{{$}}
; CHECK-NEXT: i32.and $push[[NUM1:[0-9]+]]=, $1, $pop[[NUM0]]{{$}}
; CHECK-NEXT: i32.store8 $drop=, 0($0), $pop[[NUM1]]{{$}}
; CHECK-NEXT: i32.store8 0($0), $pop[[NUM1]]{{$}}
define void @store_i32_i1(i1* %p, i32 %v) {
%t = trunc i32 %v to i1
store i1 %t, i1* %p
@ -62,7 +62,7 @@ define void @store_i32_i1(i1* %p, i32 %v) {
; CHECK-LABEL: store_i64_i1:
; CHECK: i64.const $push[[NUM0:[0-9]+]]=, 1{{$}}
; CHECK-NEXT: i64.and $push[[NUM1:[0-9]+]]=, $1, $pop[[NUM0]]{{$}}
; CHECK-NEXT: i64.store8 $drop=, 0($0), $pop[[NUM1]]{{$}}
; CHECK-NEXT: i64.store8 0($0), $pop[[NUM1]]{{$}}
define void @store_i64_i1(i1* %p, i64 %v) {
%t = trunc i64 %v to i1
store i1 %t, i1* %p

View File

@ -19,7 +19,7 @@ for.body: ; preds = %for.body, %entry
; The offset should not be folded into the store.
; CHECK: i32.const $push{{[0-9]+}}=, args+128
; CHECK: i32.add
; CHECK: i32.store $drop=, 0(
; CHECK: i32.store 0(
%arrayidx = getelementptr inbounds [32 x i32], [32 x i32]* @args, i32 0, i32 %i.04
store i32 1, i32* %arrayidx, align 4, !tbaa !1
%inc = add nuw nsw i32 %i.04, 1

View File

@ -139,7 +139,7 @@ define i32 @load_i32_with_folded_or_offset(i32 %x) {
; Same as above but with store.
; CHECK-LABEL: store_i32_with_folded_offset:
; CHECK: i32.store $drop=, 24($0), $pop0{{$}}
; CHECK: i32.store 24($0), $pop0{{$}}
define void @store_i32_with_folded_offset(i32* %p) {
%q = ptrtoint i32* %p to i32
%r = add nuw i32 %q, 24
@ -151,7 +151,7 @@ define void @store_i32_with_folded_offset(i32* %p) {
; Same as above but with store.
; CHECK-LABEL: store_i32_with_folded_gep_offset:
; CHECK: i32.store $drop=, 24($0), $pop0{{$}}
; CHECK: i32.store 24($0), $pop0{{$}}
define void @store_i32_with_folded_gep_offset(i32* %p) {
%s = getelementptr inbounds i32, i32* %p, i32 6
store i32 0, i32* %s
@ -163,7 +163,7 @@ define void @store_i32_with_folded_gep_offset(i32* %p) {
; CHECK-LABEL: store_i32_with_unfolded_gep_negative_offset:
; CHECK: i32.const $push0=, -24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i32.store 0($pop1), $pop2{{$}}
define void @store_i32_with_unfolded_gep_negative_offset(i32* %p) {
%s = getelementptr inbounds i32, i32* %p, i32 -6
store i32 0, i32* %s
@ -175,7 +175,7 @@ define void @store_i32_with_unfolded_gep_negative_offset(i32* %p) {
; CHECK-LABEL: store_i32_with_unfolded_offset:
; CHECK: i32.const $push0=, 24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i32.store 0($pop1), $pop2{{$}}
define void @store_i32_with_unfolded_offset(i32* %p) {
%q = ptrtoint i32* %p to i32
%r = add nsw i32 %q, 24
@ -189,7 +189,7 @@ define void @store_i32_with_unfolded_offset(i32* %p) {
; CHECK-LABEL: store_i32_with_unfolded_gep_offset:
; CHECK: i32.const $push0=, 24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i32.store 0($pop1), $pop2{{$}}
define void @store_i32_with_unfolded_gep_offset(i32* %p) {
%s = getelementptr i32, i32* %p, i32 6
store i32 0, i32* %s
@ -199,7 +199,7 @@ define void @store_i32_with_unfolded_gep_offset(i32* %p) {
; Same as above but with store with i64.
; CHECK-LABEL: store_i64_with_folded_offset:
; CHECK: i64.store $drop=, 24($0), $pop0{{$}}
; CHECK: i64.store 24($0), $pop0{{$}}
define void @store_i64_with_folded_offset(i64* %p) {
%q = ptrtoint i64* %p to i32
%r = add nuw i32 %q, 24
@ -211,7 +211,7 @@ define void @store_i64_with_folded_offset(i64* %p) {
; Same as above but with store with i64.
; CHECK-LABEL: store_i64_with_folded_gep_offset:
; CHECK: i64.store $drop=, 24($0), $pop0{{$}}
; CHECK: i64.store 24($0), $pop0{{$}}
define void @store_i64_with_folded_gep_offset(i64* %p) {
%s = getelementptr inbounds i64, i64* %p, i32 3
store i64 0, i64* %s
@ -223,7 +223,7 @@ define void @store_i64_with_folded_gep_offset(i64* %p) {
; CHECK-LABEL: store_i64_with_unfolded_gep_negative_offset:
; CHECK: i32.const $push0=, -24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i64.store 0($pop1), $pop2{{$}}
define void @store_i64_with_unfolded_gep_negative_offset(i64* %p) {
%s = getelementptr inbounds i64, i64* %p, i32 -3
store i64 0, i64* %s
@ -235,7 +235,7 @@ define void @store_i64_with_unfolded_gep_negative_offset(i64* %p) {
; CHECK-LABEL: store_i64_with_unfolded_offset:
; CHECK: i32.const $push0=, 24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i64.store 0($pop1), $pop2{{$}}
define void @store_i64_with_unfolded_offset(i64* %p) {
%q = ptrtoint i64* %p to i32
%r = add nsw i32 %q, 24
@ -249,7 +249,7 @@ define void @store_i64_with_unfolded_offset(i64* %p) {
; CHECK-LABEL: store_i64_with_unfolded_gep_offset:
; CHECK: i32.const $push0=, 24{{$}}
; CHECK: i32.add $push1=, $0, $pop0{{$}}
; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}}
; CHECK: i64.store 0($pop1), $pop2{{$}}
define void @store_i64_with_unfolded_gep_offset(i64* %p) {
%s = getelementptr i64, i64* %p, i32 3
store i64 0, i64* %s
@ -257,7 +257,7 @@ define void @store_i64_with_unfolded_gep_offset(i64* %p) {
}
; CHECK-LABEL: store_i32_with_folded_or_offset:
; CHECK: i32.store8 $drop=, 2($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
; CHECK: i32.store8 2($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
define void @store_i32_with_folded_or_offset(i32 %x) {
%and = and i32 %x, -4
%t0 = inttoptr i32 %and to i8*
@ -289,7 +289,7 @@ define i32 @load_i32_from_global_address() {
; CHECK-LABEL: store_i32_to_numeric_address:
; CHECK-NEXT: i32.const $push0=, 0{{$}}
; CHECK-NEXT: i32.const $push1=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, 42($pop0), $pop1{{$}}
; CHECK-NEXT: i32.store 42($pop0), $pop1{{$}}
define void @store_i32_to_numeric_address() {
%s = inttoptr i32 42 to i32*
store i32 0, i32* %s
@ -299,7 +299,7 @@ define void @store_i32_to_numeric_address() {
; CHECK-LABEL: store_i32_to_global_address:
; CHECK: i32.const $push0=, 0{{$}}
; CHECK: i32.const $push1=, 0{{$}}
; CHECK: i32.store $drop=, gv($pop0), $pop1{{$}}
; CHECK: i32.store gv($pop0), $pop1{{$}}
define void @store_i32_to_global_address() {
store i32 0, i32* @gv
ret void
@ -356,7 +356,7 @@ define i32 @load_i8_u_with_folded_gep_offset(i8* %p) {
; Fold an offset into a truncating store.
; CHECK-LABEL: store_i8_with_folded_offset:
; CHECK: i32.store8 $drop=, 24($0), $pop0{{$}}
; CHECK: i32.store8 24($0), $pop0{{$}}
define void @store_i8_with_folded_offset(i8* %p) {
%q = ptrtoint i8* %p to i32
%r = add nuw i32 %q, 24
@ -368,7 +368,7 @@ define void @store_i8_with_folded_offset(i8* %p) {
; Fold a gep offset into a truncating store.
; CHECK-LABEL: store_i8_with_folded_gep_offset:
; CHECK: i32.store8 $drop=, 24($0), $pop0{{$}}
; CHECK: i32.store8 24($0), $pop0{{$}}
define void @store_i8_with_folded_gep_offset(i8* %p) {
%s = getelementptr inbounds i8, i8* %p, i32 24
store i8 0, i8* %s
@ -382,10 +382,10 @@ define void @store_i8_with_folded_gep_offset(i8* %p) {
; CHECK: i32.load $3=, 4($0){{$}}
; CHECK: i32.load $4=, 8($0){{$}}
; CHECK: i32.load $push0=, 12($0){{$}}
; CHECK: i32.store $drop=, 12($1), $pop0{{$}}
; CHECK: i32.store $drop=, 8($1), $4{{$}}
; CHECK: i32.store $drop=, 4($1), $3{{$}}
; CHECK: i32.store $drop=, 0($1), $2{{$}}
; CHECK: i32.store 12($1), $pop0{{$}}
; CHECK: i32.store 8($1), $4{{$}}
; CHECK: i32.store 4($1), $3{{$}}
; CHECK: i32.store 0($1), $2{{$}}
define void @aggregate_load_store({i32,i32,i32,i32}* %p, {i32,i32,i32,i32}* %q) {
; volatile so that things stay in order for the tests above
%t = load volatile {i32,i32,i32,i32}, {i32, i32,i32,i32}* %p
@ -398,9 +398,9 @@ define void @aggregate_load_store({i32,i32,i32,i32}* %p, {i32,i32,i32,i32}* %q)
; CHECK-LABEL: aggregate_return:
; CHECK: i64.const $push[[L0:[0-9]+]]=, 0{{$}}
; CHECK: i64.store $drop=, 8($0):p2align=2, $pop[[L0]]{{$}}
; CHECK: i64.store 8($0):p2align=2, $pop[[L0]]{{$}}
; CHECK: i64.const $push[[L1:[0-9]+]]=, 0{{$}}
; CHECK: i64.store $drop=, 0($0):p2align=2, $pop[[L1]]{{$}}
; CHECK: i64.store 0($0):p2align=2, $pop[[L1]]{{$}}
define {i32,i32,i32,i32} @aggregate_return() {
ret {i32,i32,i32,i32} zeroinitializer
}
@ -410,13 +410,13 @@ define {i32,i32,i32,i32} @aggregate_return() {
; CHECK-LABEL: aggregate_return_without_merge:
; CHECK: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
; CHECK: i32.store8 $drop=, 14($0), $pop[[L0]]{{$}}
; CHECK: i32.store8 14($0), $pop[[L0]]{{$}}
; CHECK: i32.const $push[[L1:[0-9]+]]=, 0{{$}}
; CHECK: i32.store16 $drop=, 12($0), $pop[[L1]]{{$}}
; CHECK: i32.store16 12($0), $pop[[L1]]{{$}}
; CHECK: i32.const $push[[L2:[0-9]+]]=, 0{{$}}
; CHECK: i32.store $drop=, 8($0), $pop[[L2]]{{$}}
; CHECK: i32.store 8($0), $pop[[L2]]{{$}}
; CHECK: i64.const $push[[L3:[0-9]+]]=, 0{{$}}
; CHECK: i64.store $drop=, 0($0), $pop[[L3]]{{$}}
; CHECK: i64.store 0($0), $pop[[L3]]{{$}}
define {i64,i32,i16,i8} @aggregate_return_without_merge() {
ret {i64,i32,i16,i8} zeroinitializer
}

View File

@ -134,7 +134,7 @@ false:
; CHECK-NEXT: br_if 0, $pop[[NUM2]]{{$}}
; CHECK-NEXT: i32.lt_u $push[[NUM3:[0-9]+]]=, $3, $0{{$}}
; CHECK-NEXT: br_if 0, $pop[[NUM3]]{{$}}
; CHECK-NEXT: i32.store $drop=, 0($2), $3{{$}}
; CHECK-NEXT: i32.store 0($2), $3{{$}}
; CHECK-NEXT: .LBB8_3:
; CHECK-NEXT: end_block{{$}}
; CHECK-NEXT: return{{$}}
@ -377,7 +377,7 @@ define i32 @no_stackify_call_past_load() {
; Don't move stores past loads if there may be aliasing
; CHECK-LABEL: no_stackify_store_past_load
; CHECK: i32.store $drop=, 0($1), $0
; CHECK: i32.store 0($1), $0
; CHECK: i32.load {{.*}}, 0($2)
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0{{$}}
define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
@ -389,7 +389,7 @@ define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
; Can still stackify past invariant loads.
; CHECK-LABEL: store_past_invar_load
; CHECK: i32.store $drop=, 0($1), $0
; CHECK: i32.store 0($1), $0
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0
; CHECK: i32.load $push{{.*}}, 0($2)
; CHECK: return $pop
@ -450,7 +450,7 @@ bb10: ; preds = %bb9, %bb
; CHECK-LABEL: stackpointer_dependency:
; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
; CHECK: i32.const $push[[L0:.+]]=, 0
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L0]]),
; CHECK-NEXT: i32.store __stack_pointer($pop[[L0]]),
declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
declare i8* @llvm.frameaddress(i32)
define i32 @stackpointer_dependency(i8* readnone) {

View File

@ -6,7 +6,7 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: trunc_i8_i32:
; CHECK: i32.store8 $drop=, 0($0), $1{{$}}
; CHECK: i32.store8 0($0), $1{{$}}
define void @trunc_i8_i32(i8 *%p, i32 %v) {
%t = trunc i32 %v to i8
store i8 %t, i8* %p
@ -14,7 +14,7 @@ define void @trunc_i8_i32(i8 *%p, i32 %v) {
}
; CHECK-LABEL: trunc_i16_i32:
; CHECK: i32.store16 $drop=, 0($0), $1{{$}}
; CHECK: i32.store16 0($0), $1{{$}}
define void @trunc_i16_i32(i16 *%p, i32 %v) {
%t = trunc i32 %v to i16
store i16 %t, i16* %p
@ -22,7 +22,7 @@ define void @trunc_i16_i32(i16 *%p, i32 %v) {
}
; CHECK-LABEL: trunc_i8_i64:
; CHECK: i64.store8 $drop=, 0($0), $1{{$}}
; CHECK: i64.store8 0($0), $1{{$}}
define void @trunc_i8_i64(i8 *%p, i64 %v) {
%t = trunc i64 %v to i8
store i8 %t, i8* %p
@ -30,7 +30,7 @@ define void @trunc_i8_i64(i8 *%p, i64 %v) {
}
; CHECK-LABEL: trunc_i16_i64:
; CHECK: i64.store16 $drop=, 0($0), $1{{$}}
; CHECK: i64.store16 0($0), $1{{$}}
define void @trunc_i16_i64(i16 *%p, i64 %v) {
%t = trunc i64 %v to i16
store i16 %t, i16* %p
@ -38,7 +38,7 @@ define void @trunc_i16_i64(i16 *%p, i64 %v) {
}
; CHECK-LABEL: trunc_i32_i64:
; CHECK: i64.store32 $drop=, 0($0), $1{{$}}
; CHECK: i64.store32 0($0), $1{{$}}
define void @trunc_i32_i64(i32 *%p, i64 %v) {
%t = trunc i64 %v to i32
store i32 %t, i32* %p

View File

@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: sti32:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i32.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32(i32 *%p, i32 %v) {
store i32 %v, i32* %p
@ -17,7 +17,7 @@ define void @sti32(i32 *%p, i32 %v) {
; CHECK-LABEL: sti64:
; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: i64.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64(i64 *%p, i64 %v) {
store i64 %v, i64* %p
@ -26,7 +26,7 @@ define void @sti64(i64 *%p, i64 %v) {
; CHECK-LABEL: stf32:
; CHECK-NEXT: .param i32, f32{{$}}
; CHECK-NEXT: f32.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: f32.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @stf32(float *%p, float %v) {
store float %v, float* %p
@ -35,7 +35,7 @@ define void @stf32(float *%p, float %v) {
; CHECK-LABEL: stf64:
; CHECK-NEXT: .param i32, f64{{$}}
; CHECK-NEXT: f64.store $drop=, 0($0), $1{{$}}
; CHECK-NEXT: f64.store 0($0), $1{{$}}
; CHECK-NEXT: return{{$}}
define void @stf64(double *%p, double %v) {
store double %v, double* %p

View File

@ -16,15 +16,15 @@ define void @alloca32() noredzone {
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L9:.+]]=, $pop[[L2]], $pop[[L3]]
; CHECK-NEXT: tee_local $push[[L8:.+]]=, $[[SP:.+]]=, $pop[[L9]]{{$}}
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
%retval = alloca i32
; CHECK: i32.const $push[[L0:.+]]=, 0
; CHECK: i32.store $drop=, 12($[[SP]]), $pop[[L0]]
; CHECK: i32.store 12($[[SP]]), $pop[[L0]]
store i32 0, i32* %retval
; CHECK: i32.const $push[[L6:.+]]=, 0
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L7:.+]]=, $[[SP]], $pop[[L5]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L7]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
ret void
}
@ -39,10 +39,10 @@ define void @alloca3264() {
%r1 = alloca i32
%r2 = alloca double
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 0
; CHECK-NEXT: i32.store $drop=, 12($pop[[L5]]), $pop[[L0]]
; CHECK-NEXT: i32.store 12($pop[[L5]]), $pop[[L0]]
store i32 0, i32* %r1
; CHECK-NEXT: i64.const $push[[L1:.+]]=, 0
; CHECK-NEXT: i64.store $drop=, 0($[[SP]]), $pop[[L1]]
; CHECK-NEXT: i64.store 0($[[SP]]), $pop[[L1]]
store double 0.0, double* %r2
; CHECK-NEXT: return
ret void
@ -57,15 +57,15 @@ define void @allocarray() {
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 144{{$}}
; CHECK-NEXT: i32.sub $push[[L12:.+]]=, $pop[[L4]], $pop[[L5]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $0=, $pop[[L12]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L11]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L11]]
%r = alloca [33 x i32]
; CHECK: i32.const $push{{.+}}=, 24
; CHECK-NEXT: i32.add $push[[L3:.+]]=, $[[SP]], $pop{{.+}}
; CHECK-NEXT: i32.const $push[[L1:.+]]=, 1{{$}}
; CHECK-NEXT: i32.store $drop=, 0($pop[[L3]]), $pop[[L1]]{{$}}
; CHECK-NEXT: i32.store 0($pop[[L3]]), $pop[[L1]]{{$}}
; CHECK-NEXT: i32.const $push[[L10:.+]]=, 1{{$}}
; CHECK-NEXT: i32.store $drop=, 12(${{.+}}), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store 12(${{.+}}), $pop[[L10]]{{$}}
%p = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 0
store i32 1, i32* %p
%p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3
@ -74,7 +74,7 @@ define void @allocarray() {
; CHECK: i32.const $push[[L9:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L7:.+]]=, 144
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L7]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L9]]), $pop[[L8]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L9]]), $pop[[L8]]
ret void
}
@ -83,7 +83,7 @@ define void @non_mem_use(i8** %addr) {
; CHECK: i32.const $push[[L2:.+]]=, 48
; CHECK-NEXT: i32.sub $push[[L12:.+]]=, {{.+}}, $pop[[L2]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]
; CHECK-NEXT: i32.store $drop=, {{.+}}, $pop[[L11]]
; CHECK-NEXT: i32.store {{.+}}, $pop[[L11]]
%buf = alloca [27 x i8], align 16
%r = alloca i64
%r2 = alloca i64
@ -99,7 +99,7 @@ define void @non_mem_use(i8** %addr) {
; %buf is at SP+16
; CHECK: i32.const $push[[OFF:.+]]=, 16
; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $[[SP]], $pop[[OFF]]
; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[VAL]]
; CHECK-NEXT: i32.store 0($0), $pop[[VAL]]
%gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0
store i8* %gep, i8** %addr
ret void
@ -114,14 +114,14 @@ define void @allocarray_inbounds() {
; CHECK-NEXT: i32.const $push[[L4:.+]]=, 32{{$}}
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L3]], $pop[[L4]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L5]]), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L5]]), $pop[[L10]]{{$}}
%r = alloca [5 x i32]
; CHECK: i32.const $push[[L3:.+]]=, 1
; CHECK-DAG: i32.store $drop=, 24(${{.+}}), $pop[[L3]]
; CHECK-DAG: i32.store 24(${{.+}}), $pop[[L3]]
%p = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 0
store i32 1, i32* %p
; This store should have both the GEP and the FI folded into it.
; CHECK-DAG: i32.store {{.*}}=, 12(${{.+}}), $pop
; CHECK-DAG: i32.store 12(${{.+}}), $pop
%p2 = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 3
store i32 1, i32* %p2
call void @ext_func(i64* null);
@ -129,7 +129,7 @@ define void @allocarray_inbounds() {
; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}}
; CHECK-NEXT: i32.add $push[[L7:.+]]=, ${{.+}}, $pop[[L5]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L7]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
ret void
}
@ -142,13 +142,13 @@ define void @dynamic_alloca(i32 %alloc) {
; Target independent codegen bumps the stack pointer.
; CHECK: i32.sub
; Check that SP is written back to memory after decrement
; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}),
; CHECK: i32.store __stack_pointer($pop{{.+}}),
%r = alloca i32, i32 %alloc
; Target-independent codegen also calculates the store addr
; CHECK: call ext_func_i32@FUNCTION
call void @ext_func_i32(i32* %r)
; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
; CHECK: i32.store $drop=, __stack_pointer($pop[[L3]]), $pop{{.+}}
; CHECK: i32.store __stack_pointer($pop[[L3]]), $pop{{.+}}
ret void
}
@ -164,7 +164,7 @@ define void @dynamic_alloca_redzone(i32 %alloc) {
; CHECK-NEXT: tee_local $push[[L8:.+]]=, $0=, $pop
; CHECK-NEXT: copy_local $drop=, $pop[[L8]]{{$}}
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[L6]]{{$}}
; CHECK-NEXT: i32.store 0($0), $pop[[L6]]{{$}}
store i32 0, i32* %r
; CHECK-NEXT: return
ret void
@ -179,20 +179,20 @@ define void @dynamic_static_alloca(i32 %alloc) noredzone {
; CHECK-NEXT: i32.const $push[[L12:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L23:.+]]=, $pop[[L11]], $pop[[L12]]
; CHECK-NEXT: tee_local $push[[L22:.+]]=, $[[SP:.+]]=, $pop[[L23]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop[[L22]]
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L22]]
; Alloc and write to a static alloca
; CHECK: copy_local $push[[L21:.+]]=, $[[SP]]
; CHECK-NEXT: tee_local $push[[pushedFP:.+]]=, $[[FP:.+]]=, $pop[[L21]]
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 101
; CHECK-NEXT: i32.store $drop=, [[static_offset:.+]]($pop[[pushedFP]]), $pop[[L0]]
; CHECK-NEXT: i32.store [[static_offset:.+]]($pop[[pushedFP]]), $pop[[L0]]
%static = alloca i32
store volatile i32 101, i32* %static
; Decrement SP in the body by the dynamic amount.
; CHECK: i32.sub
; CHECK: tee_local $push{{.+}}=, $[[dynamic_local:.+]]=, $pop{{.+}}
; CHECK: i32.store {{.*}} __stack_pointer
; CHECK: i32.store __stack_pointer
%dynamic = alloca i32, i32 %alloc
; Ensure we don't modify the frame pointer after assigning it.
@ -200,9 +200,9 @@ define void @dynamic_static_alloca(i32 %alloc) noredzone {
; Ensure the static address doesn't change after modifying the stack pointer.
; CHECK: i32.const $push[[L7:.+]]=, 102
; CHECK-NEXT: i32.store $drop=, [[static_offset]]($[[FP]]), $pop[[L7]]
; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L7]]
; CHECK-NEXT: i32.const $push[[L8:.+]]=, 103
; CHECK-NEXT: i32.store $drop=, 0($[[dynamic_local]]), $pop[[L8]]
; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L8]]
store volatile i32 102, i32* %static
store volatile i32 103, i32* %dynamic
@ -216,11 +216,11 @@ define void @dynamic_static_alloca(i32 %alloc) noredzone {
; Ensure neither the static nor dynamic address changes after the second
; modification of the stack pointer.
; CHECK: i32.const $push[[L9:.+]]=, 104
; CHECK-NEXT: i32.store $drop=, [[static_offset]]($[[FP]]), $pop[[L9]]
; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L9]]
; CHECK-NEXT: i32.const $push[[L10:.+]]=, 105
; CHECK-NEXT: i32.store $drop=, 0($[[dynamic_local]]), $pop[[L10]]
; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L10]]
; CHECK-NEXT: i32.const $push[[L11:.+]]=, 106
; CHECK-NEXT: i32.store $drop=, 0($[[dynamic2_local]]), $pop[[L11]]
; CHECK-NEXT: i32.store 0($[[dynamic2_local]]), $pop[[L11]]
store volatile i32 104, i32* %static
store volatile i32 105, i32* %dynamic
store volatile i32 106, i32* %dynamic.2
@ -228,7 +228,7 @@ define void @dynamic_static_alloca(i32 %alloc) noredzone {
; Writeback to memory.
; CHECK: i32.const $push[[L17:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L18:.+]]=, $[[FP]], $pop[[L17]]
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop[[L18]]
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L18]]
ret void
}
@ -246,7 +246,7 @@ define void @llvm_stack_builtins(i32 %alloc) noredzone {
; CHECK-NOT: $[[STACK]]=
%dynamic = alloca i32, i32 %alloc
; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}), $[[STACK]]
; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[STACK]]
call void @llvm.stackrestore(i8* %stack)
ret void
@ -264,7 +264,7 @@ define void @dynamic_alloca_nouse(i32 %alloc) noredzone {
; CHECK-NOT: $[[FP]]=,
; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}), $[[FP]]
; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[FP]]
ret void
}
@ -283,7 +283,7 @@ entry:
body:
%a = phi i32* [%addr, %entry], [%b, %body]
store i32 1, i32* %a
; CHECK: i32.store {{.*}}, 0([[COPY]]),
; CHECK: i32.store 0([[COPY]]),
br i1 %cond, label %body, label %exit
exit:
ret void
@ -300,7 +300,7 @@ declare i8* @llvm.frameaddress(i32)
; CHECK-NEXT: tee_local $push[[L2:.+]]=, $[[FP:.+]]=, $pop[[L4]]{{$}}
; CHECK-NEXT: call use_i8_star@FUNCTION, $pop[[L2]]
; CHECK-NEXT: i32.const $push[[L1:.+]]=, 0{{$}}
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L1]]), $[[FP]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L1]]), $[[FP]]
define void @frameaddress_0() {
%t = call i8* @llvm.frameaddress(i32 0)
call void @use_i8_star(i8* %t)

View File

@ -15,7 +15,7 @@ define void @start(i8** %ap, ...) {
entry:
%0 = bitcast i8** %ap to i8*
; Store the second argument (the hidden vararg buffer pointer) into ap
; CHECK: i32.store $drop=, 0($0), $1
; CHECK: i32.store 0($0), $1
call void @llvm.va_start(i8* %0)
ret void
}
@ -37,7 +37,7 @@ entry:
; CHECK-LABEL: copy:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.load $push0=, 0($1){{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $pop0{{$}}
; CHECK-NEXT: i32.store 0($0), $pop0{{$}}
; CHECK-NEXT: return{{$}}
define void @copy(i8** %ap, i8** %bp) {
entry:
@ -57,7 +57,7 @@ entry:
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $1=, $pop[[NUM0]]{{$}}
; CHECK-NEXT: i32.const $push[[NUM2:[0-9]+]]=, 4{{$}}
; CHECK-NEXT: i32.add $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[NUM3]]{{$}}
; CHECK-NEXT: i32.store 0($0), $pop[[NUM3]]{{$}}
; CHECK-NEXT: i32.load $push[[NUM4:[0-9]+]]=, 0($1){{$}}
; CHECK-NEXT: return $pop[[NUM4]]{{$}}
define i8 @arg_i8(i8** %ap) {
@ -80,7 +80,7 @@ entry:
; CHECK-NEXT: tee_local $push[[NUM5:[0-9]+]]=, $1=, $pop[[NUM4]]{{$}}
; CHECK-NEXT: i32.const $push[[NUM6:[0-9]+]]=, 4{{$}}
; CHECK-NEXT: i32.add $push[[NUM7:[0-9]+]]=, $pop[[NUM5]], $pop[[NUM6]]{{$}}
; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[NUM7]]{{$}}
; CHECK-NEXT: i32.store 0($0), $pop[[NUM7]]{{$}}
; CHECK-NEXT: i32.load $push[[NUM8:[0-9]+]]=, 0($1){{$}}
; CHECK-NEXT: return $pop[[NUM8]]{{$}}
define i32 @arg_i32(i8** %ap) {
@ -141,7 +141,7 @@ bb0:
bb1:
%0 = bitcast i8** %ap to i8*
; Store the second argument (the hidden vararg buffer pointer) into ap
; CHECK: i32.store $drop=, 0($1), $2
; CHECK: i32.store 0($1), $2
call void @llvm.va_start(i8* %0)
ret void
}