[llvm] c444f03 - Reland "[SystemZ][z/OS] Fix f32 variadic argument assertion"

Neumann Hon via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 18 11:26:57 PDT 2022


Author: Mubariz Afzal
Date: 2022-07-18T14:25:17-04:00
New Revision: c444f037878c61bcc750855c6edbcdac8f0871a5

URL: https://github.com/llvm/llvm-project/commit/c444f037878c61bcc750855c6edbcdac8f0871a5
DIFF: https://github.com/llvm/llvm-project/commit/c444f037878c61bcc750855c6edbcdac8f0871a5.diff

LOG: Reland "[SystemZ][z/OS] Fix f32 variadic argument assertion"

This patch relands the f32 vararg assertion on z/OS fix that was reverted previously due to the testcase failing on non-z/OS platforms. It is now passing.

The tablegen lines that specify the XPLINK64 calling convention for promoting an f32 vararg to an f64 are effectively overwritten by the following tablegen line which bitcast an f64 vararg to an i64 (so that it can be used in the GPRs). Thus it becomes a bitcast from f32 to i64. We don't handle bitcasts for f32s and so this causes an assertion to be thrown.

We fix this by simplifying the tablegen lines to explicity show this behaviour, and allow the f32 in the bitcast case by first promoting it to an f64.

Added: 
    

Modified: 
    llvm/lib/Target/SystemZ/SystemZCallingConv.td
    llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/test/CodeGen/SystemZ/call-zos-vararg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.td b/llvm/lib/Target/SystemZ/SystemZCallingConv.td
index fdd82a01f2112..e7613bb5c0f21 100644
--- a/llvm/lib/Target/SystemZ/SystemZCallingConv.td
+++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.td
@@ -221,9 +221,10 @@ def CC_SystemZ_XPLINK64 : CallingConv<[
   // XPLINK64 ABI compliant code widens integral types smaller than i64
   // to i64 before placing the parameters either on the stack or in registers.
   CCIfType<[i32], CCIfExtend<CCPromoteToType<i64>>>,
-  // Promote f32 to f64 and bitcast to i64, if it needs to be passed in GPRS.
-  CCIfType<[f32], CCIfNotFixed<CCPromoteToType<f64>>>,
-  CCIfType<[f64], CCIfNotFixed<CCBitConvertToType<i64>>>,
+  // Promote f32 to f64 and bitcast to i64, if it needs to be passed in GPRs.
+  // Although we assign the f32 vararg to be bitcast, it will first be promoted
+  // to an f64 within convertValVTToLocVT().
+  CCIfType<[f32, f64], CCIfNotFixed<CCBitConvertToType<i64>>>,
   // long double, can only be passed in GPR2 and GPR3, if available,
   // hence R2Q
   CCIfType<[f128], CCIfNotFixed<CCCustom<"CC_XPLINK64_Allocate128BitVararg">>>,

diff  --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 42c1c77f14e4b..ac4531262187c 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1404,8 +1404,12 @@ static SDValue convertValVTToLocVT(SelectionDAG &DAG, const SDLoc &DL,
     return DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Value);
   case CCValAssign::BCvt: {
     assert(VA.getLocVT() == MVT::i64 || VA.getLocVT() == MVT::i128);
-    assert(VA.getValVT().isVector() || VA.getValVT() == MVT::f64 ||
-           VA.getValVT() == MVT::f128);
+    assert(VA.getValVT().isVector() || VA.getValVT() == MVT::f32 ||
+           VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::f128);
+    // For an f32 vararg we need to first promote it to an f64 and then
+    // bitcast it to an i64.
+    if (VA.getValVT() == MVT::f32 && VA.getLocVT() == MVT::i64)
+      Value = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f64, Value);
     MVT BitCastToType = VA.getValVT().isVector() && VA.getLocVT() == MVT::i64
                             ? MVT::v2i64
                             : VA.getLocVT();

diff  --git a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
index 2af2c29c1d53f..a26bca9d84353 100644
--- a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
+++ b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
@@ -189,6 +189,28 @@ entry:
   ret i64 %retval
 }
 
+; CHECK-LABEL: call_vararg_float0
+; CHECK:       lghi  1, 1
+; CHECK:       llihf 2, 1073692672
+define i64 @call_vararg_float0() {
+entry:
+  %retval = call i64 (i64, ...) @pass_vararg2(i64 1, float 1.953125)
+  ret i64 %retval
+}
+
+; CHECK-LABEL: call_vararg_float1
+; CHECK:       larl  1, @CPI17_0
+; CHECK:       le  0, 0(1)
+; CHECK:       llihf 0, 1073692672
+; CHECK:       llihh 2, 16384
+; CHECK:       llihh 3, 16392
+; CHECK:       stg  0, 2200(4)
+define i64 @call_vararg_float1() {
+entry:
+  %retval = call i64 (float, ...) @pass_vararg4(float 1.0, float 2.0, float 3.0, float 1.953125)
+  ret i64 %retval
+}
+
 ; Derived from C source:
 ; #define _VARARG_EXT_
 ; #include <stdarg.h>
@@ -227,3 +249,4 @@ declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
 declare i64 @pass_vararg1(fp128 %arg0, ...)
 declare i64 @pass_vararg2(i64 %arg0, ...)
 declare i64 @pass_vararg3(...)
+declare i64 @pass_vararg4(float, ...)


        


More information about the llvm-commits mailing list