ro created this revision.
ro added reviewers: efriedma, brad.
Herald added subscribers: Sanitizers, s.egerton, dexonsmith, jrtc27, simoncook, 
fedor.sergeev, hiraditya, mgorny, jyknight.
Herald added projects: clang, Sanitizers, LLVM.
ro requested review of this revision.
The SysVr4 SPARC psABI prescribes 128-bit `long double` on 32-bit Sparc, and 
Solaris follows that as do some other OSes.  However, `clang` doesn't support 
that.

**This is not yet complete, but I need guidance in some points and believe it's 
easier to do so here than in the corresponding Bug 42493**

There are several noteworthy issues:

- `long double` is 128-bit IEEEquad format, but with 64-bit alignment unlike 
SPARC V9 which uses 128-bit alignment.
- `long double` is passed and returned by reference, just like structures and 
unions.
- `long double _Complex`, a Sun extension not in the psABI, is always returned 
in registers.
- `compiler-rt` uses `__uint128_t` for `long double` support which isn't 
available for 32-bit compilations by default.  It's currently enabled with 
`-fforce-enable-int128` which `gcc` doesn't support.

Right now the basic `long double` support seems to work (need to double-check 
with GCC's `gcc.dg/compat` testsuite), but compiling 
`compiler-rt/lib/builtins/divtc3.c` fails:

  Assertion failed: isRegLoc(), file 
/vol/llvm/src/llvm-project/local/llvm/include/llvm/CodeGen/CallingConvLower.h, 
line 150
  
  11 libc.so.1 0xffffffff7edfb158 _assert + 104
  12 clang-12  0x00000001038fdf90 
llvm::SparcTargetLowering::LowerCall_32(llvm::TargetLowering::CallLoweringInfo&,
 llvm::SmallVectorImpl<llvm::SDValue>&) const + 11888
  13 clang-12  0x00000001038f9010 
llvm::SparcTargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, 
llvm::SmallVectorImpl<llvm::SDValue>&) const + 60
  14 clang-12  0x0000000106062f54 
llvm::TargetLowering::LowerCallTo(llvm::TargetLowering::CallLoweringInfo&) 
const + 7724
  15 clang-12  0x0000000106039704 (anonymous 
namespace)::SelectionDAGLegalize::ExpandLibCall(llvm::RTLIB::Libcall, 
llvm::SDNode*, bool) + 1896

Besides, something will have to be done about the `__uint128_t` requirement on 
32-bit targets, probably using a union with `uint64_t` members.

I'm currently lost here and will need some guidance how to proceed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89130

Files:
  clang/lib/Basic/Targets/Sparc.h
  clang/lib/CodeGen/TargetInfo.cpp
  compiler-rt/lib/builtins/CMakeLists.txt
  compiler-rt/lib/builtins/int_types.h
  compiler-rt/test/builtins/CMakeLists.txt
  compiler-rt/test/builtins/Unit/divtc3_test.c
  llvm/lib/Target/Sparc/SparcCallingConv.td
  llvm/lib/Target/Sparc/SparcISelLowering.cpp

Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp
===================================================================
--- llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -507,9 +507,6 @@
     SDValue Load ;
     if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
       Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
-    } else if (VA.getValVT() == MVT::f128) {
-      report_fatal_error("SPARCv8 does not handle f128 in calls; "
-                         "pass indirectly");
     } else {
       // We shouldn't see any other value types here.
       llvm_unreachable("Unexpected ValVT encountered in frame lowering.");
Index: llvm/lib/Target/Sparc/SparcCallingConv.td
===================================================================
--- llvm/lib/Target/Sparc/SparcCallingConv.td
+++ llvm/lib/Target/Sparc/SparcCallingConv.td
@@ -34,6 +34,8 @@
   CCIfType<[i32], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
   CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3]>>,
   CCIfType<[f64], CCAssignToReg<[D0, D1]>>,
+  CCIfInReg<CCIfType<[f128] , CCAssignToReg<[Q0, Q1]>>>,
+  CCIfType<[f128], CCAssignToStack<16, 8>>,
   CCIfType<[v2i32], CCCustom<"CC_Sparc_Assign_Ret_Split_64">>
 ]>;
 
Index: compiler-rt/test/builtins/Unit/divtc3_test.c
===================================================================
--- compiler-rt/test/builtins/Unit/divtc3_test.c
+++ compiler-rt/test/builtins/Unit/divtc3_test.c
@@ -2,10 +2,6 @@
 // REQUIRES: librt_has_divtc3
 // REQUIRES: c99-complex
 
-//
-// Bug 42493
-// XFAIL: sparc-target-arch
-//
 #include <stdio.h>
 
 #include "int_lib.h"
Index: compiler-rt/test/builtins/CMakeLists.txt
===================================================================
--- compiler-rt/test/builtins/CMakeLists.txt
+++ compiler-rt/test/builtins/CMakeLists.txt
@@ -39,7 +39,7 @@
     string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
   endif()
 
-  if (${arch} STREQUAL "riscv32")
+  if("${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
     list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128)
     string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
   endif()
Index: compiler-rt/lib/builtins/int_types.h
===================================================================
--- compiler-rt/lib/builtins/int_types.h
+++ compiler-rt/lib/builtins/int_types.h
@@ -64,7 +64,7 @@
 } udwords;
 
 #if defined(__LP64__) || defined(__wasm__) || defined(__mips64) ||             \
-    defined(__riscv) || defined(_WIN64)
+    defined(__riscv) || defined(__sparc) || defined(_WIN64)
 #define CRT_HAS_128BIT
 #endif
 
Index: compiler-rt/lib/builtins/CMakeLists.txt
===================================================================
--- compiler-rt/lib/builtins/CMakeLists.txt
+++ compiler-rt/lib/builtins/CMakeLists.txt
@@ -668,9 +668,9 @@
         list(APPEND BUILTIN_CFLAGS -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
       endif()
 
-      # For RISCV32, we must force enable int128 for compiling long
-      # double routines.
-      if("${arch}" STREQUAL "riscv32")
+      # For RISCV32 and 32-bit SPARC, we must force enable int128 for compiling
+      # long double routines.
+      if("${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
         list(APPEND BUILTIN_CFLAGS -fforce-enable-int128)
       endif()
 
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -9198,6 +9198,7 @@
 
 private:
   ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType Ty) const;
   void computeInfo(CGFunctionInfo &FI) const override;
 };
 } // end anonymous namespace
@@ -9205,12 +9206,25 @@
 
 ABIArgInfo
 SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
+  if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
+    return getNaturalAlignIndirect(Ty);
+
   if (Ty->isAnyComplexType()) {
-    return ABIArgInfo::getDirect();
-  }
-  else {
-    return DefaultABIInfo::classifyReturnType(Ty);
-  }
+    auto AI = ABIArgInfo::getDirect();
+    AI.setInReg(true);
+    return AI;
+  }
+
+  return DefaultABIInfo::classifyReturnType(Ty);
+}
+
+ABIArgInfo
+SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
+  // FIXME: Need to check for BuiltinType::LongDouble, too?
+  if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
+    return getNaturalAlignIndirect(Ty);
+
+  return DefaultABIInfo::classifyArgumentType(Ty);
 }
 
 void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
Index: clang/lib/Basic/Targets/Sparc.h
===================================================================
--- clang/lib/Basic/Targets/Sparc.h
+++ clang/lib/Basic/Targets/Sparc.h
@@ -166,6 +166,15 @@
       PtrDiffType = SignedLong;
       break;
     }
+
+    if (getTriple().isOSSolaris()) {
+      // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
+      // aligned.
+      LongDoubleWidth = 128;
+      LongDoubleAlign = 64;
+      LongDoubleFormat = &llvm::APFloat::IEEEquad();
+    }
+
     // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're
     // willing to do atomic ops on up to 64 bits.
     MaxAtomicPromoteWidth = 64;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D89130: [WIP][Sparc] ... Rainer Orth via Phabricator via cfe-commits

Reply via email to