diff options
4 files changed, 30 insertions, 20 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp index 9ffd04e581d..4ebea68c58a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp @@ -83,7 +83,7 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) { case WebAssembly::STORE16_I32: case WebAssembly::STORE8_I64: case WebAssembly::STORE16_I64: - case WebAssembly::STORE32_I64: + case WebAssembly::STORE32_I64: { assert(MI.getOperand(3).getImm() == 0 && "ISel should set p2align operands to 0"); assert(MI.hasOneMemOperand() && @@ -95,9 +95,15 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) { assert(MI.getDesc().OpInfo[3].OperandType == WebAssembly::OPERAND_P2ALIGN && "Load and store instructions should have a p2align operand"); - MI.getOperand(3).setImm( - Log2_64((*MI.memoperands_begin())->getAlignment())); + 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); break; + } default: break; } diff --git a/llvm/test/CodeGen/WebAssembly/byval.ll b/llvm/test/CodeGen/WebAssembly/byval.ll index 35ec4e351ed..232a4a21022 100644 --- a/llvm/test/CodeGen/WebAssembly/byval.ll +++ b/llvm/test/CodeGen/WebAssembly/byval.ll @@ -55,8 +55,8 @@ define void @byval_arg_align8(%SmallStruct* %ptr) { ; CHECK: i32.const $push[[L1:.+]]=, 16 ; CHECK-NEXT: i32.sub [[SP:.+]]=, {{.+}}, $pop[[L1]] ; Copy the SmallStruct argument to the stack (SP+8, original SP-8) - ; CHECK: i32.load $push[[L4:.+]]=, 0($0):p2align=3 - ; CHECK-NEXT: i32.store {{.*}}=, 8([[SP]]):p2align=3, $pop[[L4]] + ; CHECK: i32.load $push[[L4:.+]]=, 0($0){{$}} + ; CHECK-NEXT: i32.store {{.*}}=, 8([[SP]]), $pop[[L4]]{{$}} ; 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]] diff --git a/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll b/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll index 89279fba1e5..3c48a1ad245 100644 --- a/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll +++ b/llvm/test/CodeGen/WebAssembly/i32-load-store-alignment.ll @@ -49,10 +49,12 @@ define i32 @ldi32(i32 *%p) { ret i32 %v } +; 8 is greater than the default alignment so it is ignored. + ; CHECK-LABEL: ldi32_a8: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0):p2align=3{{$}} +; CHECK-NEXT: i32.load $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i32 @ldi32_a8(i32 *%p) { %v = load i32, i32* %p, align 8 @@ -74,7 +76,7 @@ define i8 @ldi8_a1(i8 *%p) { ; CHECK-LABEL: ldi8_a2: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}} +; CHECK-NEXT: i32.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i8 @ldi8_a2(i8 *%p) { %v = load i8, i8* %p, align 2 @@ -104,7 +106,7 @@ define i16 @ldi16_a2(i16 *%p) { ; CHECK-LABEL: ldi16_a4: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}} +; CHECK-NEXT: i32.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i16 @ldi16_a4(i16 *%p) { %v = load i16, i16* %p, align 4 @@ -155,7 +157,7 @@ define void @sti32(i32 *%p, i32 %v) { ; CHECK-LABEL: sti32_a8: ; CHECK-NEXT: .param i32, i32{{$}} -; CHECK-NEXT: i32.store $discard=, 0($0):p2align=3, $1{{$}} +; CHECK-NEXT: i32.store $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti32_a8(i32 *%p, i32 %v) { store i32 %v, i32* %p, align 8 @@ -175,7 +177,7 @@ define void @sti8_a1(i8 *%p, i8 %v) { ; CHECK-LABEL: sti8_a2: ; CHECK-NEXT: .param i32, i32{{$}} -; CHECK-NEXT: i32.store8 $discard=, 0($0):p2align=1, $1{{$}} +; CHECK-NEXT: i32.store8 $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti8_a2(i8 *%p, i8 %v) { store i8 %v, i8* %p, align 2 @@ -202,7 +204,7 @@ define void @sti16_a2(i16 *%p, i16 %v) { ; CHECK-LABEL: sti16_a4: ; CHECK-NEXT: .param i32, i32{{$}} -; CHECK-NEXT: i32.store16 $discard=, 0($0):p2align=2, $1{{$}} +; CHECK-NEXT: i32.store16 $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti16_a4(i16 *%p, i16 %v) { store i16 %v, i16* %p, align 4 diff --git a/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll b/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll index 3290b9c7376..38bae3007e7 100644 --- a/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll +++ b/llvm/test/CodeGen/WebAssembly/i64-load-store-alignment.ll @@ -35,7 +35,7 @@ define i64 @ldi64_a4(i64 *%p) { ret i64 %v } -; 8 is the default alignment for i32 so no attribute is needed. +; 8 is the default alignment for i64 so no attribute is needed. ; CHECK-LABEL: ldi64_a8: ; CHECK-NEXT: .param i32{{$}} @@ -59,10 +59,12 @@ define i64 @ldi64(i64 *%p) { ret i64 %v } +; 16 is greater than the default alignment so it is ignored. + ; CHECK-LABEL: ldi64_a16: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i64{{$}} -; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0):p2align=4{{$}} +; CHECK-NEXT: i64.load $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i64 @ldi64_a16(i64 *%p) { %v = load i64, i64* %p, align 16 @@ -85,7 +87,7 @@ define i64 @ldi8_a1(i8 *%p) { ; CHECK-LABEL: ldi8_a2: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i64{{$}} -; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0):p2align=1{{$}} +; CHECK-NEXT: i64.load8_u $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i64 @ldi8_a2(i8 *%p) { %v = load i8, i8* %p, align 2 @@ -118,7 +120,7 @@ define i64 @ldi16_a2(i16 *%p) { ; CHECK-LABEL: ldi16_a4: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i64{{$}} -; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0):p2align=2{{$}} +; CHECK-NEXT: i64.load16_u $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i64 @ldi16_a4(i16 *%p) { %v = load i16, i16* %p, align 4 @@ -162,7 +164,7 @@ define i64 @ldi32_a4(i32 *%p) { ; CHECK-LABEL: ldi32_a8: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i64{{$}} -; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0):p2align=3{{$}} +; CHECK-NEXT: i64.load32_u $push[[NUM:[0-9]+]]=, 0($0){{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i64 @ldi32_a8(i32 *%p) { %v = load i32, i32* %p, align 8 @@ -223,7 +225,7 @@ define void @sti64(i64 *%p, i64 %v) { ; CHECK-LABEL: sti64_a16: ; CHECK-NEXT: .param i32, i64{{$}} -; CHECK-NEXT: i64.store $discard=, 0($0):p2align=4, $1{{$}} +; CHECK-NEXT: i64.store $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti64_a16(i64 *%p, i64 %v) { store i64 %v, i64* %p, align 16 @@ -244,7 +246,7 @@ define void @sti8_a1(i8 *%p, i64 %w) { ; CHECK-LABEL: sti8_a2: ; CHECK-NEXT: .param i32, i64{{$}} -; CHECK-NEXT: i64.store8 $discard=, 0($0):p2align=1, $1{{$}} +; CHECK-NEXT: i64.store8 $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti8_a2(i8 *%p, i64 %w) { %v = trunc i64 %w to i8 @@ -274,7 +276,7 @@ define void @sti16_a2(i16 *%p, i64 %w) { ; CHECK-LABEL: sti16_a4: ; CHECK-NEXT: .param i32, i64{{$}} -; CHECK-NEXT: i64.store16 $discard=, 0($0):p2align=2, $1{{$}} +; CHECK-NEXT: i64.store16 $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti16_a4(i16 *%p, i64 %w) { %v = trunc i64 %w to i16 @@ -314,7 +316,7 @@ define void @sti32_a4(i32 *%p, i64 %w) { ; CHECK-LABEL: sti32_a8: ; CHECK-NEXT: .param i32, i64{{$}} -; CHECK-NEXT: i64.store32 $discard=, 0($0):p2align=3, $1{{$}} +; CHECK-NEXT: i64.store32 $discard=, 0($0), $1{{$}} ; CHECK-NEXT: return{{$}} define void @sti32_a8(i32 *%p, i64 %w) { %v = trunc i64 %w to i32 |