[llvm] r343756 - [RISCV] Bugfix for floats passed on the stack with the ILP32 ABI on RV32F

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 4 00:28:49 PDT 2018


Author: asb
Date: Thu Oct  4 00:28:49 2018
New Revision: 343756

URL: http://llvm.org/viewvc/llvm-project?rev=343756&view=rev
Log:
[RISCV] Bugfix for floats passed on the stack with the ILP32 ABI on RV32F

f32 values passed on the stack would previously cause an assertion in 
unpackFromMemLoc.. This would only trigger in the presence of the F extension 
making f32 a legal type. Otherwise the f32 would be legalized.

This patch fixes that by keeping LocVT=f32 when a float is passed on the 
stack. It also adds test coverage for this case, and tests that also 
demonstrate lw/sw/flw/fsw will be selected when most profitable. i.e. there is 
no unnecessary i32<->f32 conversion in registers.

Added:
    llvm/trunk/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll
Modified:
    llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp

Modified: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp?rev=343756&r1=343755&r2=343756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp Thu Oct  4 00:28:49 2018
@@ -834,10 +834,14 @@ static bool CC_RISCV(const DataLayout &D
 
   if (Reg) {
     State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
-  } else {
-    State.addLoc(
-        CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
+    return false;
+  }
+
+  if (ValVT == MVT::f32) {
+    LocVT = MVT::f32;
+    LocInfo = CCValAssign::Full;
   }
+  State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
   return false;
 }
 
@@ -1046,7 +1050,6 @@ SDValue RISCVTargetLowering::LowerFormal
 
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     CCValAssign &VA = ArgLocs[i];
-    assert(VA.getLocVT() == XLenVT && "Unhandled argument type");
     SDValue ArgValue;
     // Passing f64 on RV32D with a soft float ABI must be handled as a special
     // case.

Added: llvm/trunk/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll?rev=343756&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/calling-conv-rv32f-ilp32.ll Thu Oct  4 00:28:49 2018
@@ -0,0 +1,81 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32IF
+
+; Exercises the ILP32 calling convention code in the case that f32 is a legal
+; type. As well as testing that lowering is correct, these tests also aim to
+; check that floating point load/store or integer load/store is chosen
+; optimally when floats are passed on the stack.
+
+define float @onstack_f32_noop(i64 %a, i64 %b, i64 %c, i64 %d, float %e, float %f) nounwind {
+; RV32IF-LABEL: onstack_f32_noop:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    lw a0, 4(sp)
+; RV32IF-NEXT:    ret
+  ret float %f
+}
+
+define float @onstack_f32_fadd(i64 %a, i64 %b, i64 %c, i64 %d, float %e, float %f) nounwind {
+; RV32IF-LABEL: onstack_f32_fadd:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    flw ft0, 4(sp)
+; RV32IF-NEXT:    flw ft1, 0(sp)
+; RV32IF-NEXT:    fadd.s ft0, ft1, ft0
+; RV32IF-NEXT:    fmv.x.w a0, ft0
+; RV32IF-NEXT:    ret
+  %1 = fadd float %e, %f
+  ret float %1
+}
+
+define float @caller_onstack_f32_noop(float %a) nounwind {
+; RV32IF-LABEL: caller_onstack_f32_noop:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    addi sp, sp, -16
+; RV32IF-NEXT:    sw ra, 12(sp)
+; RV32IF-NEXT:    sw a0, 4(sp)
+; RV32IF-NEXT:    lui a0, 264704
+; RV32IF-NEXT:    sw a0, 0(sp)
+; RV32IF-NEXT:    addi a0, zero, 1
+; RV32IF-NEXT:    addi a2, zero, 2
+; RV32IF-NEXT:    addi a4, zero, 3
+; RV32IF-NEXT:    addi a6, zero, 4
+; RV32IF-NEXT:    mv a1, zero
+; RV32IF-NEXT:    mv a3, zero
+; RV32IF-NEXT:    mv a5, zero
+; RV32IF-NEXT:    mv a7, zero
+; RV32IF-NEXT:    call onstack_f32_noop
+; RV32IF-NEXT:    lw ra, 12(sp)
+; RV32IF-NEXT:    addi sp, sp, 16
+; RV32IF-NEXT:    ret
+  %1 = call float @onstack_f32_noop(i64 1, i64 2, i64 3, i64 4, float 5.0, float %a)
+  ret float %1
+}
+
+define float @caller_onstack_f32_fadd(float %a, float %b) nounwind {
+; RV32IF-LABEL: caller_onstack_f32_fadd:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    addi sp, sp, -16
+; RV32IF-NEXT:    sw ra, 12(sp)
+; RV32IF-NEXT:    fmv.w.x ft0, a0
+; RV32IF-NEXT:    fmv.w.x ft1, a1
+; RV32IF-NEXT:    fsub.s ft2, ft1, ft0
+; RV32IF-NEXT:    fsw ft2, 4(sp)
+; RV32IF-NEXT:    fadd.s ft0, ft0, ft1
+; RV32IF-NEXT:    fsw ft0, 0(sp)
+; RV32IF-NEXT:    addi a0, zero, 1
+; RV32IF-NEXT:    addi a2, zero, 2
+; RV32IF-NEXT:    addi a4, zero, 3
+; RV32IF-NEXT:    addi a6, zero, 4
+; RV32IF-NEXT:    mv a1, zero
+; RV32IF-NEXT:    mv a3, zero
+; RV32IF-NEXT:    mv a5, zero
+; RV32IF-NEXT:    mv a7, zero
+; RV32IF-NEXT:    call onstack_f32_noop
+; RV32IF-NEXT:    lw ra, 12(sp)
+; RV32IF-NEXT:    addi sp, sp, 16
+; RV32IF-NEXT:    ret
+  %1 = fadd float %a, %b
+  %2 = fsub float %b, %a
+  %3 = call float @onstack_f32_noop(i64 1, i64 2, i64 3, i64 4, float %1, float %2)
+  ret float %3
+}




More information about the llvm-commits mailing list