[llvm] [TargetLowering] Use Correct VT for Multi-out Asm (PR #116024)

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 13 12:10:50 PST 2024


https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/116024

>From 77592322d19cf46b512263932db11c5647b36a0b Mon Sep 17 00:00:00 2001
From: Sam Elliott <quic_aelliott at quicinc.com>
Date: Wed, 13 Nov 2024 02:51:42 -0800
Subject: [PATCH 1/3] [TargetLowering] Use Correct VT for Multi-out Asm

This was overlooked in 7d940432c46be83b8fcb5dbefee439585fa820cd - 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.

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.
---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  2 +-
 llvm/test/CodeGen/AArch64/ls64-inline-asm.ll  | 34 +++++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 8287565336b54d..1940ed25ecfd0d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -5753,7 +5753,7 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
       assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
       if (auto *STy = dyn_cast<StructType>(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 ed91f4adb8d3fb..d3d8ecb99f45ec 100644
--- a/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll
+++ b/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll
@@ -103,3 +103,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
+; }

>From 3b0198c961d9f6e60ef3d431c539fbaef7cffb85 Mon Sep 17 00:00:00 2001
From: Sam Elliott <quic_aelliott at quicinc.com>
Date: Wed, 13 Nov 2024 03:38:27 -0800
Subject: [PATCH 2/3] fixup! [TargetLowering] Use Correct VT for Multi-out Asm

---
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 1940ed25ecfd0d..bf68538e083fdd 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<StructType>(Call.getType())) {
         OpInfo.ConstraintVT =
-            getAsmOperandValueType(DL, STy->getElementType(ResNo)).getSimpleVT();
+            getAsmOperandValueType(DL, STy->getElementType(ResNo))
+                .getSimpleVT();
       } else {
         assert(ResNo == 0 && "Asm only has one result!");
         OpInfo.ConstraintVT =

>From c5f81900dcf29a4a65ac3b95d760ee7f7eadba05 Mon Sep 17 00:00:00 2001
From: Sam Elliott <quic_aelliott at quicinc.com>
Date: Wed, 13 Nov 2024 12:10:30 -0800
Subject: [PATCH 3/3] fixup! fixup! [TargetLowering] Use Correct VT for
 Multi-out Asm

---
 llvm/test/CodeGen/AArch64/ls64-inline-asm.ll | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll b/llvm/test/CodeGen/AArch64/ls64-inline-asm.ll
index d3d8ecb99f45ec..bb324c3fd6bcd1 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



More information about the llvm-commits mailing list