Skip to content

Commit 862f42e

Browse files
authored
[TargetLowering] Use Correct VT for Multi-out Asm (#116024)
This was overlooked in 7d94043 - when inline assembly has multiple outputs, they are returned as members of a struct, and the `getAsmOperandType` needs to be called for each member of struct. The difference between this and the single-output case is that in the latter, there isn't a struct wrapping the outputs. I noticed this when trying to use the same mechanism in the RISC-V backend. Committing two tests: - One that shows a crash before this change, which is fixed by this change. - One (commented out) that shows a different crash with tied inputs/outputs. This is commented as it is not fixed by this change and needs more work in target-independent inline asm handling code.
1 parent 8fde648 commit 862f42e

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5753,7 +5753,8 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
57535753
assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
57545754
if (auto *STy = dyn_cast<StructType>(Call.getType())) {
57555755
OpInfo.ConstraintVT =
5756-
getSimpleValueType(DL, STy->getElementType(ResNo));
5756+
getAsmOperandValueType(DL, STy->getElementType(ResNo))
5757+
.getSimpleVT();
57575758
} else {
57585759
assert(ResNo == 0 && "Asm only has one result!");
57595760
OpInfo.ConstraintVT =

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

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22
; RUN: llc -mtriple=aarch64 -mattr=+ls64 -verify-machineinstrs -o - %s | FileCheck %s
33

4-
%struct.foo = type { [8 x i64] }
5-
64
define void @load(ptr %output, ptr %addr) {
75
; CHECK-LABEL: load:
86
; CHECK: // %bb.0: // %entry
@@ -103,3 +101,37 @@ entry:
103101
call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 %s.sroa.0.0.insert.insert, ptr %addr)
104102
ret void
105103
}
104+
105+
define void @multi_output(ptr %addr) {
106+
; CHECK-LABEL: multi_output:
107+
; CHECK: // %bb.0: // %entry
108+
; CHECK-NEXT: //APP
109+
; CHECK-NEXT: ld64b x0, [x0]
110+
; CHECK-NEXT: mov x8, x0
111+
; CHECK-NEXT: //NO_APP
112+
; CHECK-NEXT: stp x6, x7, [x8, #48]
113+
; CHECK-NEXT: stp x4, x5, [x8, #32]
114+
; CHECK-NEXT: stp x2, x3, [x8, #16]
115+
; CHECK-NEXT: stp x0, x1, [x8]
116+
; CHECK-NEXT: ret
117+
entry:
118+
%val = call { i512, ptr } asm sideeffect "ld64b $0, [$2]; mov $1, $2", "=r,=r,r,~{memory}"(ptr %addr)
119+
%val0 = extractvalue { i512, ptr } %val, 0
120+
%val1 = extractvalue { i512, ptr } %val, 1
121+
store i512 %val0, ptr %val1, align 8
122+
ret void
123+
}
124+
125+
; FIXME: This case still crashes in RegsForValue::AddInlineAsmOperands without
126+
; additional changes. I believe this is a bug in target-independent code, that
127+
; is worked around in the RISC-V and SystemZ backends, but should almost
128+
; certainly be fixed instead.
129+
; define void @tied_constraints(ptr %addr) {
130+
; entry:
131+
; %in = load i512, ptr %addr, align 8
132+
; %val = call { i512, ptr } asm sideeffect "nop", "=r,=r,0,1,~{memory}"(i512 %in, ptr %addr)
133+
; %val0 = extractvalue { i512, ptr } %val, 0
134+
; %val1 = extractvalue { i512, ptr } %val, 1
135+
; store i512 %val0, ptr %val1, align 8
136+
; ret void
137+
; }

0 commit comments

Comments
 (0)