Skip to content

Commit bc6695c

Browse files
committed
Merging r354846:
------------------------------------------------------------------------ r354846 | djg | 2019-02-25 21:20:19 -0800 (Mon, 25 Feb 2019) | 12 lines [WebAssembly] Properly align fp128 arguments in outgoing varargs arguments For outgoing varargs arguments, it's necessary to check the OrigAlign field of the corresponding OutputArg entry to determine argument alignment, rather than just computing an alignment from the argument value type. This is because types like fp128 are split into multiple argument values, with narrower types that don't reflect the ABI alignment of the full fp128. This fixes the printf("printfL: %4.*Lf\n", 2, lval); testcase. Differential Revision: https://reviews.llvm.org/D58656 ------------------------------------------------------------------------ llvm-svn: 360826
1 parent e58d5a4 commit bc6695c

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -669,13 +669,16 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
669669
if (IsVarArg) {
670670
// Outgoing non-fixed arguments are placed in a buffer. First
671671
// compute their offsets and the total amount of buffer space needed.
672-
for (SDValue Arg :
673-
make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
672+
for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) {
673+
const ISD::OutputArg &Out = Outs[I];
674+
SDValue &Arg = OutVals[I];
674675
EVT VT = Arg.getValueType();
675676
assert(VT != MVT::iPTR && "Legalized args should be concrete");
676677
Type *Ty = VT.getTypeForEVT(*DAG.getContext());
678+
unsigned Align = std::max(Out.Flags.getOrigAlign(),
679+
Layout.getABITypeAlignment(Ty));
677680
unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
678-
Layout.getABITypeAlignment(Ty));
681+
Align);
679682
CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
680683
Offset, VT.getSimpleVT(),
681684
CCValAssign::Full));

llvm/test/CodeGen/WebAssembly/varargs.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,32 @@ define void @nonlegal_fixed(fp128 %x, ...) nounwind {
163163
ret void
164164
}
165165

166+
; Test that an fp128 argument is properly aligned and allocated
167+
; within a vararg buffer.
168+
169+
; CHECK-LABEL: call_fp128_alignment:
170+
; CHECK: global.get $push7=, __stack_pointer
171+
; CHECK-NEXT: i32.const $push8=, 32
172+
; CHECK-NEXT: i32.sub $push12=, $pop7, $pop8
173+
; CHECK-NEXT: local.tee $push11=, $1=, $pop12
174+
; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop11
175+
; CHECK-NEXT: i32.const $push0=, 24
176+
; CHECK-NEXT: i32.add $push1=, $1, $pop0
177+
; CHECK-NEXT: i64.const $push2=, -9223372036854775808
178+
; CHECK-NEXT: i64.store 0($pop1), $pop2
179+
; CHECK-NEXT: i32.const $push3=, 16
180+
; CHECK-NEXT: i32.add $push4=, $1, $pop3
181+
; CHECK-NEXT: i64.const $push5=, 1
182+
; CHECK-NEXT: i64.store 0($pop4), $pop5
183+
; CHECK-NEXT: i32.const $push6=, 7
184+
; CHECK-NEXT: i32.store 0($1), $pop6
185+
; CHECK-NEXT: call callee@FUNCTION, $1
186+
define void @call_fp128_alignment(i8* %p) {
187+
entry:
188+
call void (...) @callee(i8 7, fp128 0xL00000000000000018000000000000000)
189+
ret void
190+
}
191+
166192
declare void @llvm.va_start(i8*)
167193
declare void @llvm.va_end(i8*)
168194
declare void @llvm.va_copy(i8*, i8*)

0 commit comments

Comments
 (0)