mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[RISCV] Fix a crash when lowering split float arguments
Lowering certain float vectors without legal vector types could cause a crash due to a bad interaction between passing floats via GPRs and argument splitting. Split vector floats appear just like scalar floats. Under certain situations we choose to pass these float arguments via GPRs and use an XLenVT location and set the 'BCvt' info to track how they must be converted back to floating-point values. However, later logic for handling split arguments may take over, in which case we lose the previous information and set the 'Indirect' info, thus incorrectly lowering to integer types. I don't believe that we would have come across the notion of split floating-point arguments before. This patch addresses the issue by updating the lowering so that split arguments are only passed indirectly when they are scalar integer types. This has some change to how we lower some larger illegal float vectors, as can be seen in 'fastcc-float.ll' where the vector is now passed partly in registers and partly on the stack. Reviewed By: luismarques Differential Revision: https://reviews.llvm.org/D102852
This commit is contained in:
parent
ecdacaf414
commit
4c884f4ac3
@ -7130,7 +7130,7 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
|
|||||||
// Split arguments might be passed indirectly, so keep track of the pending
|
// Split arguments might be passed indirectly, so keep track of the pending
|
||||||
// values. Split vectors are passed via a mix of registers and indirectly, so
|
// values. Split vectors are passed via a mix of registers and indirectly, so
|
||||||
// treat them as we would any other argument.
|
// treat them as we would any other argument.
|
||||||
if (!LocVT.isVector() && (ArgFlags.isSplit() || !PendingLocs.empty())) {
|
if (ValVT.isScalarInteger() && (ArgFlags.isSplit() || !PendingLocs.empty())) {
|
||||||
LocVT = XLenVT;
|
LocVT = XLenVT;
|
||||||
LocInfo = CCValAssign::Indirect;
|
LocInfo = CCValAssign::Indirect;
|
||||||
PendingLocs.push_back(
|
PendingLocs.push_back(
|
||||||
@ -7143,7 +7143,8 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
|
|||||||
|
|
||||||
// If the split argument only had two elements, it should be passed directly
|
// If the split argument only had two elements, it should be passed directly
|
||||||
// in registers or on the stack.
|
// in registers or on the stack.
|
||||||
if (!LocVT.isVector() && ArgFlags.isSplitEnd() && PendingLocs.size() <= 2) {
|
if (ValVT.isScalarInteger() && ArgFlags.isSplitEnd() &&
|
||||||
|
PendingLocs.size() <= 2) {
|
||||||
assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()");
|
assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()");
|
||||||
// Apply the normal calling convention rules to the first half of the
|
// Apply the normal calling convention rules to the first half of the
|
||||||
// split argument.
|
// split argument.
|
||||||
|
63
test/CodeGen/RISCV/calling-conv-vector-float.ll
Normal file
63
test/CodeGen/RISCV/calling-conv-vector-float.ll
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
|
||||||
|
; RUN: | FileCheck -check-prefix=RV64 %s
|
||||||
|
; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi=lp64f -verify-machineinstrs < %s \
|
||||||
|
; RUN: | FileCheck -check-prefix=RV64LP64F %s
|
||||||
|
|
||||||
|
define <2 x float> @callee_v2f32(<2 x float> %x, <2 x float> %y) {
|
||||||
|
; RV64-LABEL: callee_v2f32:
|
||||||
|
; RV64: # %bb.0:
|
||||||
|
; RV64-NEXT: fmv.w.x ft0, a2
|
||||||
|
; RV64-NEXT: fmv.w.x ft1, a0
|
||||||
|
; RV64-NEXT: fmv.w.x ft2, a3
|
||||||
|
; RV64-NEXT: fmv.w.x ft3, a1
|
||||||
|
; RV64-NEXT: fadd.s ft2, ft3, ft2
|
||||||
|
; RV64-NEXT: fadd.s ft0, ft1, ft0
|
||||||
|
; RV64-NEXT: fmv.x.w a0, ft0
|
||||||
|
; RV64-NEXT: fmv.x.w a1, ft2
|
||||||
|
; RV64-NEXT: ret
|
||||||
|
;
|
||||||
|
; RV64LP64F-LABEL: callee_v2f32:
|
||||||
|
; RV64LP64F: # %bb.0:
|
||||||
|
; RV64LP64F-NEXT: fadd.s fa0, fa0, fa2
|
||||||
|
; RV64LP64F-NEXT: fadd.s fa1, fa1, fa3
|
||||||
|
; RV64LP64F-NEXT: ret
|
||||||
|
%z = fadd <2 x float> %x, %y
|
||||||
|
ret <2 x float> %z
|
||||||
|
}
|
||||||
|
|
||||||
|
define <4 x float> @callee_v4f32(<4 x float> %x, <4 x float> %y) {
|
||||||
|
; RV64-LABEL: callee_v4f32:
|
||||||
|
; RV64: # %bb.0:
|
||||||
|
; RV64-NEXT: fmv.w.x ft0, a4
|
||||||
|
; RV64-NEXT: fmv.w.x ft1, a7
|
||||||
|
; RV64-NEXT: fmv.w.x ft2, a3
|
||||||
|
; RV64-NEXT: fmv.w.x ft3, a6
|
||||||
|
; RV64-NEXT: fmv.w.x ft4, a2
|
||||||
|
; RV64-NEXT: fmv.w.x ft5, a5
|
||||||
|
; RV64-NEXT: fmv.w.x ft6, a1
|
||||||
|
; RV64-NEXT: flw ft7, 0(sp)
|
||||||
|
; RV64-NEXT: fadd.s ft5, ft6, ft5
|
||||||
|
; RV64-NEXT: fadd.s ft3, ft4, ft3
|
||||||
|
; RV64-NEXT: fadd.s ft1, ft2, ft1
|
||||||
|
; RV64-NEXT: fadd.s ft0, ft0, ft7
|
||||||
|
; RV64-NEXT: fsw ft0, 12(a0)
|
||||||
|
; RV64-NEXT: fsw ft1, 8(a0)
|
||||||
|
; RV64-NEXT: fsw ft3, 4(a0)
|
||||||
|
; RV64-NEXT: fsw ft5, 0(a0)
|
||||||
|
; RV64-NEXT: ret
|
||||||
|
;
|
||||||
|
; RV64LP64F-LABEL: callee_v4f32:
|
||||||
|
; RV64LP64F: # %bb.0:
|
||||||
|
; RV64LP64F-NEXT: fadd.s ft0, fa0, fa4
|
||||||
|
; RV64LP64F-NEXT: fadd.s ft1, fa1, fa5
|
||||||
|
; RV64LP64F-NEXT: fadd.s ft2, fa2, fa6
|
||||||
|
; RV64LP64F-NEXT: fadd.s ft3, fa3, fa7
|
||||||
|
; RV64LP64F-NEXT: fsw ft3, 12(a0)
|
||||||
|
; RV64LP64F-NEXT: fsw ft2, 8(a0)
|
||||||
|
; RV64LP64F-NEXT: fsw ft1, 4(a0)
|
||||||
|
; RV64LP64F-NEXT: fsw ft0, 0(a0)
|
||||||
|
; RV64LP64F-NEXT: ret
|
||||||
|
%z = fadd <4 x float> %x, %y
|
||||||
|
ret <4 x float> %z
|
||||||
|
}
|
@ -18,38 +18,38 @@ define float @caller(<32 x float> %A) nounwind {
|
|||||||
; CHECK: # %bb.0:
|
; CHECK: # %bb.0:
|
||||||
; CHECK-NEXT: addi sp, sp, -64
|
; CHECK-NEXT: addi sp, sp, -64
|
||||||
; CHECK-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
|
; CHECK-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
|
||||||
; CHECK-NEXT: flw fa0, 0(a0)
|
; CHECK-NEXT: fmv.w.x fa0, a0
|
||||||
; CHECK-NEXT: flw fa1, 4(a0)
|
; CHECK-NEXT: fmv.w.x fa1, a1
|
||||||
; CHECK-NEXT: flw fa2, 8(a0)
|
; CHECK-NEXT: fmv.w.x fa2, a2
|
||||||
; CHECK-NEXT: flw fa3, 12(a0)
|
; CHECK-NEXT: fmv.w.x fa3, a3
|
||||||
; CHECK-NEXT: flw fa4, 16(a0)
|
; CHECK-NEXT: fmv.w.x fa4, a4
|
||||||
; CHECK-NEXT: flw fa5, 20(a0)
|
; CHECK-NEXT: flw ft0, 64(sp)
|
||||||
; CHECK-NEXT: flw fa6, 24(a0)
|
; CHECK-NEXT: flw ft1, 68(sp)
|
||||||
; CHECK-NEXT: flw fa7, 28(a0)
|
; CHECK-NEXT: flw ft2, 72(sp)
|
||||||
; CHECK-NEXT: flw ft0, 32(a0)
|
; CHECK-NEXT: flw ft3, 76(sp)
|
||||||
; CHECK-NEXT: flw ft1, 36(a0)
|
; CHECK-NEXT: flw ft4, 80(sp)
|
||||||
; CHECK-NEXT: flw ft2, 40(a0)
|
; CHECK-NEXT: flw ft5, 84(sp)
|
||||||
; CHECK-NEXT: flw ft3, 44(a0)
|
; CHECK-NEXT: flw ft6, 88(sp)
|
||||||
; CHECK-NEXT: flw ft4, 48(a0)
|
; CHECK-NEXT: flw ft7, 92(sp)
|
||||||
; CHECK-NEXT: flw ft5, 52(a0)
|
; CHECK-NEXT: flw ft8, 96(sp)
|
||||||
; CHECK-NEXT: flw ft6, 56(a0)
|
; CHECK-NEXT: flw ft9, 100(sp)
|
||||||
; CHECK-NEXT: flw ft7, 60(a0)
|
; CHECK-NEXT: flw ft10, 104(sp)
|
||||||
; CHECK-NEXT: flw ft8, 64(a0)
|
; CHECK-NEXT: flw ft11, 108(sp)
|
||||||
; CHECK-NEXT: flw ft9, 68(a0)
|
; CHECK-NEXT: flw fs0, 112(sp)
|
||||||
; CHECK-NEXT: flw ft10, 72(a0)
|
; CHECK-NEXT: flw fs1, 116(sp)
|
||||||
; CHECK-NEXT: flw ft11, 76(a0)
|
; CHECK-NEXT: flw fs2, 120(sp)
|
||||||
; CHECK-NEXT: flw fs0, 80(a0)
|
; CHECK-NEXT: flw fs3, 124(sp)
|
||||||
; CHECK-NEXT: flw fs1, 84(a0)
|
; CHECK-NEXT: flw fs4, 128(sp)
|
||||||
; CHECK-NEXT: flw fs2, 88(a0)
|
; CHECK-NEXT: flw fs5, 132(sp)
|
||||||
; CHECK-NEXT: flw fs3, 92(a0)
|
; CHECK-NEXT: flw fs6, 136(sp)
|
||||||
; CHECK-NEXT: flw fs4, 96(a0)
|
; CHECK-NEXT: flw fs7, 140(sp)
|
||||||
; CHECK-NEXT: flw fs5, 100(a0)
|
; CHECK-NEXT: flw fs8, 144(sp)
|
||||||
; CHECK-NEXT: flw fs6, 104(a0)
|
; CHECK-NEXT: flw fs9, 148(sp)
|
||||||
; CHECK-NEXT: flw fs7, 108(a0)
|
; CHECK-NEXT: flw fs10, 152(sp)
|
||||||
; CHECK-NEXT: flw fs8, 112(a0)
|
; CHECK-NEXT: flw fs11, 156(sp)
|
||||||
; CHECK-NEXT: flw fs9, 116(a0)
|
; CHECK-NEXT: fmv.w.x fa5, a5
|
||||||
; CHECK-NEXT: flw fs10, 120(a0)
|
; CHECK-NEXT: fmv.w.x fa6, a6
|
||||||
; CHECK-NEXT: flw fs11, 124(a0)
|
; CHECK-NEXT: fmv.w.x fa7, a7
|
||||||
; CHECK-NEXT: fsw fs11, 44(sp)
|
; CHECK-NEXT: fsw fs11, 44(sp)
|
||||||
; CHECK-NEXT: fsw fs10, 40(sp)
|
; CHECK-NEXT: fsw fs10, 40(sp)
|
||||||
; CHECK-NEXT: fsw fs9, 36(sp)
|
; CHECK-NEXT: fsw fs9, 36(sp)
|
||||||
@ -62,7 +62,7 @@ define float @caller(<32 x float> %A) nounwind {
|
|||||||
; CHECK-NEXT: fsw fs2, 8(sp)
|
; CHECK-NEXT: fsw fs2, 8(sp)
|
||||||
; CHECK-NEXT: fsw fs1, 4(sp)
|
; CHECK-NEXT: fsw fs1, 4(sp)
|
||||||
; CHECK-NEXT: fsw fs0, 0(sp)
|
; CHECK-NEXT: fsw fs0, 0(sp)
|
||||||
; CHECK-NEXT: call callee
|
; CHECK-NEXT: call callee@plt
|
||||||
; CHECK-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
|
; CHECK-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
|
||||||
; CHECK-NEXT: addi sp, sp, 64
|
; CHECK-NEXT: addi sp, sp, 64
|
||||||
; CHECK-NEXT: ret
|
; CHECK-NEXT: ret
|
||||||
|
Loading…
Reference in New Issue
Block a user