From d21237cb1193cceadd758eba4d4d714733358ed1 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Sun, 5 Sep 2021 17:27:22 +0200 Subject: [PATCH] [SelectionDAGBuilder] Bugfix in visitInlineAsm() In case of a virtual register tied to a phys-def, the register class needs to be computed. Make sure that this works generally also with fast regalloc by using TLI.getRegClassFor() whenever possible, and make only the case of 'Untyped' use getMinimalPhysRegClass(). Fixes https://bugs.llvm.org/show_bug.cgi?id=51699. Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D109291 (cherry picked from commit 118997d8e931dcb4c6e972611a7e4febcc33a061) --- .../SelectionDAG/SelectionDAGBuilder.cpp | 6 ++++-- test/CodeGen/X86/20210831-inlineasm.ll | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/X86/20210831-inlineasm.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index a0854839397..bd2ebfd0bd3 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8677,8 +8677,10 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call, RegisterSDNode *R = dyn_cast(AsmNodeOperands[CurOp+1]); Register TiedReg = R->getReg(); MVT RegVT = R->getSimpleValueType(0); - const TargetRegisterClass *RC = TiedReg.isVirtual() ? - MRI.getRegClass(TiedReg) : TRI.getMinimalPhysRegClass(TiedReg); + const TargetRegisterClass *RC = + TiedReg.isVirtual() ? MRI.getRegClass(TiedReg) + : RegVT != MVT::Untyped ? TLI.getRegClassFor(RegVT) + : TRI.getMinimalPhysRegClass(TiedReg); unsigned NumRegs = InlineAsm::getNumOperandRegisters(OpFlag); for (unsigned i = 0; i != NumRegs; ++i) Regs.push_back(MRI.createVirtualRegister(RC)); diff --git a/test/CodeGen/X86/20210831-inlineasm.ll b/test/CodeGen/X86/20210831-inlineasm.ll new file mode 100644 index 00000000000..065695db9e3 --- /dev/null +++ b/test/CodeGen/X86/20210831-inlineasm.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -O0 -mtriple=x86_64-unknown-linux-gnu +; https://bugs.llvm.org/show_bug.cgi?id=51699 + +%"[]u8" = type { i8*, i64 } +%std.mem.Allocator = type { void ({ %"[]u8", i16 }*, %std.builtin.StackTrace*, %std.mem.Allocator*, i64, i29, i29, i64)*, void ({ i64, i16 }*, %std.builtin.StackTrace*, %std.mem.Allocator*, %"[]u8"*, i29, i64, i29, i64)* } +%std.builtin.StackTrace = type { i64, %"[]usize" } +%"[]usize" = type { i64*, i64 } + +define void @fun(%"[]u8"* %0) #0 { +Entry: + %1 = alloca [6 x i64], align 8 + br label %ErrRetContinue + +ErrRetContinue: ; preds = %Entry + %2 = call i64 asm sideeffect "rolq $$3, %rdi ; rolq $$13, %rdi\0Arolq $$61, %rdi ; rolq $$51, %rdi\0Axchgq %rbx,%rbx\0A", "={rdx},{rax},0,~{cc},~{memory}"(i64 undef, i64 0) + %3 = call fastcc i64 undef(%std.mem.Allocator* undef, %"[]u8"* %0, i29 undef, i64 0, i29 0, i64 undef) + ret void +} + +attributes #0 = { sspstrong }