[PATCH] D58656: [WebAssembly] Properly align fp128 arguments in outgoing varargs arguments

Dan Gohman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 25 16:49:56 PST 2019


sunfish created this revision.
sunfish added a reviewer: jgravelle-google.
Herald added subscribers: jdoerfert, aheejin, sbc100, dschuff.
Herald added a project: LLVM.

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.


Repository:
  rL LLVM

https://reviews.llvm.org/D58656

Files:
  lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  test/CodeGen/WebAssembly/varargs.ll


Index: lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -672,13 +672,16 @@
   if (IsVarArg) {
     // Outgoing non-fixed arguments are placed in a buffer. First
     // compute their offsets and the total amount of buffer space needed.
-    for (SDValue Arg :
-         make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) {
+    for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) {
+        const ISD::OutputArg &Out = Outs[I];
+        SDValue &Arg = OutVals[I];
       EVT VT = Arg.getValueType();
       assert(VT != MVT::iPTR && "Legalized args should be concrete");
       Type *Ty = VT.getTypeForEVT(*DAG.getContext());
+      unsigned Align = std::max(Out.Flags.getOrigAlign(),
+                                Layout.getABITypeAlignment(Ty));
       unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
-                                             Layout.getABITypeAlignment(Ty));
+                                             Align);
       CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(),
                                         Offset, VT.getSimpleVT(),
                                         CCValAssign::Full));
Index: test/CodeGen/WebAssembly/varargs.ll
===================================================================
--- test/CodeGen/WebAssembly/varargs.ll
+++ test/CodeGen/WebAssembly/varargs.ll
@@ -163,6 +163,32 @@
   ret void
 }
 
+; Test that an fp128 argument is properly aligned and allocated
+; within a vararg buffer.
+
+; CHECK-LABEL: call_fp128_alignment:
+; CHECK:      global.get      $push7=, __stack_pointer at GLOBAL
+; CHECK-NEXT: i32.const       $push8=, 32
+; CHECK-NEXT: i32.sub         $push12=, $pop7, $pop8
+; CHECK-NEXT: local.tee       $push11=, $1=, $pop12
+; CHECK-NEXT: global.set      __stack_pointer at GLOBAL, $pop11
+; CHECK-NEXT: i32.const       $push0=, 24
+; CHECK-NEXT: i32.add         $push1=, $1, $pop0
+; CHECK-NEXT: i64.const       $push2=, -9223372036854775808
+; CHECK-NEXT: i64.store       0($pop1), $pop2
+; CHECK-NEXT: i32.const       $push3=, 16
+; CHECK-NEXT: i32.add         $push4=, $1, $pop3
+; CHECK-NEXT: i64.const       $push5=, 1
+; CHECK-NEXT: i64.store       0($pop4), $pop5
+; CHECK-NEXT: i32.const       $push6=, 7
+; CHECK-NEXT: i32.store       0($1), $pop6
+; CHECK-NEXT: call            callee at FUNCTION, $1
+define void @call_fp128_alignment(i8* %p) {
+entry:
+  call void (...) @callee(i8 7, fp128 0xL00000000000000018000000000000000)
+  ret void
+}
+
 declare void @llvm.va_start(i8*)
 declare void @llvm.va_end(i8*)
 declare void @llvm.va_copy(i8*, i8*)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58656.188276.patch
Type: text/x-patch
Size: 2762 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190226/6ee413ed/attachment-0001.bin>


More information about the llvm-commits mailing list