Skip to content

Commit 1983acc

Browse files
committed
[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
1 parent 515105f commit 1983acc

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8087,10 +8087,9 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call) {
80878087
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
80888088
}
80898089

8090-
OpInfo.ConstraintVT =
8091-
OpInfo
8092-
.getCallOperandValEVT(*DAG.getContext(), TLI, DAG.getDataLayout())
8093-
.getSimpleVT();
8090+
EVT VT = OpInfo.getCallOperandValEVT(*DAG.getContext(), TLI,
8091+
DAG.getDataLayout());
8092+
OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
80948093
} else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
80958094
// The return value of the call is this value. As such, there is no
80968095
// corresponding argument.

llvm/test/CodeGen/AArch64/arm64-inline-asm.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,18 @@ define void @test_no_hash_in_lane_specifier() {
282282
tail call void asm sideeffect "fmla v2.4s, v0.4s, v1.s[$0]", "I"(i32 1) #1
283283
ret void
284284
}
285+
define void @test_vector_too_large_r_m(<9 x float>* nocapture readonly %0) {
286+
; CHECK-LABEL: test_vector_too_large_r_m
287+
; CHECK: ldr [[S:s[0-9]+]], [x0, #32]
288+
; CHECK-DAG: ldp [[Q0:q[0-9]+]], [[Q1:q[0-9]+]], [x0]
289+
; CHECK: str [[S]], [sp, #32]
290+
; CHECK-DAG stp [[Q0]], [[Q1]], [sp]
291+
; CHECK: ; InlineAsm Start
292+
;
293+
entry:
294+
%m.addr = alloca <9 x float>, align 16
295+
%m = load <9 x float>, <9 x float>* %0, align 16
296+
store <9 x float> %m, <9 x float>* %m.addr, align 16
297+
call void asm sideeffect "", "=*r|m,0,~{memory}"(<9 x float>* nonnull %m.addr, <9 x float> %m)
298+
ret void
299+
}

llvm/test/CodeGen/AArch64/inlineasm-illegal-type.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
; CHECK: error: couldn't allocate output register for constraint '{d0}'
44
; CHECK: error: couldn't allocate output register for constraint 'w'
5+
; CHECK: error: couldn't allocate input reg for constraint 'w'
6+
; CHECK: error: couldn't allocate input reg for constraint 'w'
57

68
define hidden double @test1(double %xx) local_unnamed_addr #0 {
79
entry:
@@ -15,3 +17,16 @@ entry:
1517
ret double %0
1618
}
1719

20+
define void @test_vector_too_large(<8 x float>* nocapture readonly %0) {
21+
entry:
22+
%m = load <8 x float>, <8 x float>* %0, align 16
23+
tail call void asm sideeffect "fadd.4s v4, v4, $0", "w,~{memory}"(<8 x float> %m)
24+
ret void
25+
}
26+
27+
define void @test_vector_no_mvt(<9 x float>* nocapture readonly %0) {
28+
entry:
29+
%m = load <9 x float>, <9 x float>* %0, align 16
30+
tail call void asm sideeffect "fadd.4s v4, v4, $0", "w,~{memory}"(<9 x float> %m)
31+
ret void
32+
}

0 commit comments

Comments
 (0)