mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[SelDAGBuilder] Do not require simple VTs for constraints.
In some cases, the values passed to `asm sideeffect` calls cannot be mapped directly to simple MVTs. Currently, we crash in the backend if that happens. An example can be found in the @test_vector_too_large_r_m test case, where we pass <9 x float> vectors. In practice, this can happen in cases like the simple C example below. using vec = float __attribute__((ext_vector_type(9))); void f1 (vec m) { asm volatile("" : "+r,m"(m) : : "memory"); } One case that use "+r,m" constraints for arbitrary data types in practice is google-benchmark's DoNotOptimize. This patch updates visitInlineAsm so that it use MVT::Other for constraints with complex VTs. It looks like the rest of the backend correctly deals with that and properly legalizes the type. And we still report an error if there are no registers to satisfy the constraint. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D91710
This commit is contained in:
parent
b6c52319b7
commit
9328b6a7fd
@ -8087,10 +8087,9 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call) {
|
||||
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
|
||||
}
|
||||
|
||||
OpInfo.ConstraintVT =
|
||||
OpInfo
|
||||
.getCallOperandValEVT(*DAG.getContext(), TLI, DAG.getDataLayout())
|
||||
.getSimpleVT();
|
||||
EVT VT = OpInfo.getCallOperandValEVT(*DAG.getContext(), TLI,
|
||||
DAG.getDataLayout());
|
||||
OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
|
||||
} else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
|
||||
// The return value of the call is this value. As such, there is no
|
||||
// corresponding argument.
|
||||
|
@ -282,3 +282,18 @@ define void @test_no_hash_in_lane_specifier() {
|
||||
tail call void asm sideeffect "fmla v2.4s, v0.4s, v1.s[$0]", "I"(i32 1) #1
|
||||
ret void
|
||||
}
|
||||
define void @test_vector_too_large_r_m(<9 x float>* nocapture readonly %0) {
|
||||
; CHECK-LABEL: test_vector_too_large_r_m
|
||||
; CHECK: ldr [[S:s[0-9]+]], [x0, #32]
|
||||
; CHECK-DAG: ldp [[Q0:q[0-9]+]], [[Q1:q[0-9]+]], [x0]
|
||||
; CHECK: str [[S]], [sp, #32]
|
||||
; CHECK-DAG stp [[Q0]], [[Q1]], [sp]
|
||||
; CHECK: ; InlineAsm Start
|
||||
;
|
||||
entry:
|
||||
%m.addr = alloca <9 x float>, align 16
|
||||
%m = load <9 x float>, <9 x float>* %0, align 16
|
||||
store <9 x float> %m, <9 x float>* %m.addr, align 16
|
||||
call void asm sideeffect "", "=*r|m,0,~{memory}"(<9 x float>* nonnull %m.addr, <9 x float> %m)
|
||||
ret void
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
; CHECK: error: couldn't allocate output register for constraint '{d0}'
|
||||
; CHECK: error: couldn't allocate output register for constraint 'w'
|
||||
; CHECK: error: couldn't allocate input reg for constraint 'w'
|
||||
; CHECK: error: couldn't allocate input reg for constraint 'w'
|
||||
|
||||
define hidden double @test1(double %xx) local_unnamed_addr #0 {
|
||||
entry:
|
||||
@ -15,3 +17,16 @@ entry:
|
||||
ret double %0
|
||||
}
|
||||
|
||||
define void @test_vector_too_large(<8 x float>* nocapture readonly %0) {
|
||||
entry:
|
||||
%m = load <8 x float>, <8 x float>* %0, align 16
|
||||
tail call void asm sideeffect "fadd.4s v4, v4, $0", "w,~{memory}"(<8 x float> %m)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vector_no_mvt(<9 x float>* nocapture readonly %0) {
|
||||
entry:
|
||||
%m = load <9 x float>, <9 x float>* %0, align 16
|
||||
tail call void asm sideeffect "fadd.4s v4, v4, $0", "w,~{memory}"(<9 x float> %m)
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user