diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 8287565336b54..bf68538e083fd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5753,7 +5753,8 @@ TargetLowering::ParseConstraints(const DataLayout &DL, assert(!Call.getType()->isVoidTy() && "Bad inline asm!"); if (auto *STy = dyn_cast(Call.getType())) { OpInfo.ConstraintVT = - getSimpleValueType(DL, STy->getElementType(ResNo)); + getAsmOperandValueType(DL, STy->getElementType(ResNo)) + .getSimpleVT(); } else { assert(ResNo == 0 && "Asm only has one result!"); OpInfo.ConstraintVT = diff --git a/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll b/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll index ed91f4adb8d3f..bb324c3fd6bcd 100644 --- a/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=aarch64 -mattr=+ls64 -verify-machineinstrs -o - %s | FileCheck %s -%struct.foo = type { [8 x i64] } - define void @load(ptr %output, ptr %addr) { ; CHECK-LABEL: load: ; CHECK: // %bb.0: // %entry @@ -103,3 +101,37 @@ entry: call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 %s.sroa.0.0.insert.insert, ptr %addr) ret void } + +define void @multi_output(ptr %addr) { +; CHECK-LABEL: multi_output: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: //APP +; CHECK-NEXT: ld64b x0, [x0] +; CHECK-NEXT: mov x8, x0 +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: stp x6, x7, [x8, #48] +; CHECK-NEXT: stp x4, x5, [x8, #32] +; CHECK-NEXT: stp x2, x3, [x8, #16] +; CHECK-NEXT: stp x0, x1, [x8] +; CHECK-NEXT: ret +entry: + %val = call { i512, ptr } asm sideeffect "ld64b $0, [$2]; mov $1, $2", "=r,=r,r,~{memory}"(ptr %addr) + %val0 = extractvalue { i512, ptr } %val, 0 + %val1 = extractvalue { i512, ptr } %val, 1 + store i512 %val0, ptr %val1, align 8 + ret void +} + +; FIXME: This case still crashes in RegsForValue::AddInlineAsmOperands without +; additional changes. I believe this is a bug in target-independent code, that +; is worked around in the RISC-V and SystemZ backends, but should almost +; certainly be fixed instead. +; define void @tied_constraints(ptr %addr) { +; entry: +; %in = load i512, ptr %addr, align 8 +; %val = call { i512, ptr } asm sideeffect "nop", "=r,=r,0,1,~{memory}"(i512 %in, ptr %addr) +; %val0 = extractvalue { i512, ptr } %val, 0 +; %val1 = extractvalue { i512, ptr } %val, 1 +; store i512 %val0, ptr %val1, align 8 +; ret void +; }