From 7a92e735b62219292645662d2d1bee77e62423ab Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 12 Sep 2016 11:20:10 +0000 Subject: [PATCH] GlobalISel: disambiguate types when printing MIR Some generic instructions have multiple types. While in theory these always be discovered by inspecting the single definition of each generic vreg, in practice those definitions won't always be local and traipsing through a big function to find them will not be fun. So this changes MIRPrinter to print out the type of uses as well as defs, if they're known to be different or not known to be the same. On the parsing side, we're a little more flexible: provided each register is given a type in at least one place it's mentioned (and all types are consistent) we accept the MIR. This doesn't introduce ambiguity but makes writing tests manually a bit less painful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281204 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MIRParser/MIParser.cpp | 27 +++-- lib/CodeGen/MIRParser/MIRParser.cpp | 4 +- lib/CodeGen/MIRPrinter.cpp | 42 ++++++-- lib/CodeGen/MachineRegisterInfo.cpp | 2 - .../AArch64/GlobalISel/arm64-irtranslator.ll | 100 +++++++++--------- .../AArch64/GlobalISel/call-translator.ll | 2 +- .../AArch64/GlobalISel/legalize-cmp.mir | 4 +- .../AArch64/GlobalISel/legalize-combines.mir | 16 +-- .../AArch64/GlobalISel/legalize-fcmp.mir | 4 +- .../GlobalISel/legalize-load-store.mir | 24 ++--- .../AArch64/GlobalISel/legalize-simple.mir | 12 +-- .../X86/expected-integer-after-tied-def.mir | 2 +- .../X86/expected-tied-def-after-lparen.mir | 2 +- 13 files changed, 139 insertions(+), 102 deletions(-) diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 696ba48e97c..2147651c4ef 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -877,7 +877,7 @@ bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { if (!consumeIfPresent(MIToken::kw_tied_def)) - return error("expected 'tied-def' after '('"); + return true; if (Token.isNot(MIToken::IntegerLiteral)) return error("expected an integer literal after 'tied-def'"); if (getUnsigned(TiedDefIdx)) @@ -957,16 +957,28 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest, if (!TargetRegisterInfo::isVirtualRegister(Reg)) return error("subregister index expects a virtual register"); } + MachineRegisterInfo &MRI = MF.getRegInfo(); if ((Flags & RegState::Define) == 0) { if (consumeIfPresent(MIToken::lparen)) { unsigned Idx; - if (parseRegisterTiedDefIndex(Idx)) - return true; - TiedDefIdx = Idx; + if (!parseRegisterTiedDefIndex(Idx)) + TiedDefIdx = Idx; + else { + // Try a redundant low-level type. + LLT Ty; + if (parseLowLevelType(Token.location(), Ty)) + return error("expected tied-def or low-level type after '('"); + + if (expectAndConsume(MIToken::rparen)) + return true; + + if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) + return error("inconsistent type for generic virtual register"); + + MRI.setType(Reg, Ty); + } } } else if (consumeIfPresent(MIToken::lparen)) { - MachineRegisterInfo &MRI = MF.getRegInfo(); - // Virtual registers may have a size with GlobalISel. if (!TargetRegisterInfo::isVirtualRegister(Reg)) return error("unexpected size on physical register"); @@ -980,6 +992,9 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest, if (expectAndConsume(MIToken::rparen)) return true; + if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) + return error("inconsistent type for generic virtual register"); + MRI.setType(Reg, Ty); } else if (PFS.GenericVRegs.count(Reg)) { // Generic virtual registers must have a size. diff --git a/lib/CodeGen/MIRParser/MIRParser.cpp b/lib/CodeGen/MIRParser/MIRParser.cpp index e7fdcc0afd8..104d7d18812 100644 --- a/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/lib/CodeGen/MIRParser/MIRParser.cpp @@ -415,7 +415,7 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS, if (StringRef(VReg.Class.Value).equals("_")) { // This is a generic virtual register. // The size will be set appropriately when we reach the definition. - Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1)); + Reg = RegInfo.createGenericVirtualRegister(LLT{}); PFS.GenericVRegs.insert(Reg); } else { const auto *RC = getRegClass(MF, VReg.Class.Value); @@ -428,7 +428,7 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS, VReg.Class.SourceRange.Start, Twine("use of undefined register class or register bank '") + VReg.Class.Value + "'"); - Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1)); + Reg = RegInfo.createGenericVirtualRegister(LLT{}); RegInfo.setRegBank(Reg, *RegBank); PFS.GenericVRegs.insert(Reg); } diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index e293a0743eb..11d84d7c350 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -14,6 +14,7 @@ #include "MIRPrinter.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/CodeGen/MachineConstantPool.h" @@ -123,7 +124,7 @@ public: void printTargetFlags(const MachineOperand &Op); void print(const MachineOperand &Op, const TargetRegisterInfo *TRI, unsigned I, bool ShouldPrintRegisterTies, - const MachineRegisterInfo *MRI = nullptr, bool IsDef = false); + LLT TypeToPrint, bool IsDef = false); void print(const MachineMemOperand &Op); void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); @@ -223,7 +224,7 @@ void MIRPrinter::convert(yaml::MachineFunction &MF, VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower(); else { VReg.Class = std::string("_"); - assert(RegInfo.getType(Reg).isValid() && + assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) && "Generic registers must have a valid type"); } unsigned PreferredReg = RegInfo.getSimpleHint(Reg); @@ -542,6 +543,27 @@ static bool hasComplexRegisterTies(const MachineInstr &MI) { return false; } +static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx, + SmallBitVector &PrintedTypes, + const MachineRegisterInfo &MRI) { + const MachineOperand &Op = MI.getOperand(OpIdx); + if (!Op.isReg()) + return LLT{}; + + if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands()) + return MRI.getType(Op.getReg()); + + auto &OpInfo = MI.getDesc().OpInfo[OpIdx]; + if (!OpInfo.isGenericType()) + return MRI.getType(Op.getReg()); + + if (PrintedTypes[OpInfo.getGenericTypeIndex()]) + return LLT{}; + + PrintedTypes.set(OpInfo.getGenericTypeIndex()); + return MRI.getType(Op.getReg()); +} + void MIPrinter::print(const MachineInstr &MI) { const auto *MF = MI.getParent()->getParent(); const auto &MRI = MF->getRegInfo(); @@ -553,6 +575,7 @@ void MIPrinter::print(const MachineInstr &MI) { if (MI.isCFIInstruction()) assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); + SmallBitVector PrintedTypes(8); bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI); unsigned I = 0, E = MI.getNumOperands(); for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && @@ -560,7 +583,8 @@ void MIPrinter::print(const MachineInstr &MI) { ++I) { if (I) OS << ", "; - print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, &MRI, + print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, + getTypeToPrint(MI, I, PrintedTypes, MRI), /*IsDef=*/true); } @@ -576,7 +600,8 @@ void MIPrinter::print(const MachineInstr &MI) { for (; I < E; ++I) { if (NeedComma) OS << ", "; - print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies); + print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, + getTypeToPrint(MI, I, PrintedTypes, MRI)); NeedComma = true; } @@ -748,8 +773,8 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) { } void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, - unsigned I, bool ShouldPrintRegisterTies, - const MachineRegisterInfo *MRI, bool IsDef) { + unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, + bool IsDef) { printTargetFlags(Op); switch (Op.getType()) { case MachineOperand::MO_Register: @@ -776,9 +801,8 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; - assert((!IsDef || MRI) && "for IsDef, MRI must be provided"); - if (IsDef && MRI->getType(Op.getReg()).isValid()) - OS << '(' << MRI->getType(Op.getReg()) << ')'; + if (TypeToPrint.isValid()) + OS << '(' << TypeToPrint << ')'; break; case MachineOperand::MO_Immediate: OS << Op.getImm(); diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index a16211cfa2b..ca89a1ff7bc 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -126,8 +126,6 @@ void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) { unsigned MachineRegisterInfo::createGenericVirtualRegister(LLT Ty) { - assert(Ty.isValid() && "Cannot create empty virtual register"); - // New virtual register number. unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs()); VRegInfo.grow(Reg); diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index e462400b3cf..fea1f5370ef 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -82,8 +82,8 @@ end: ; ; Check that we emit the correct branch. ; CHECK: [[ADDR:%.*]](p0) = COPY %x0 -; CHECK: [[TST:%.*]](s1) = G_LOAD [[ADDR]] -; CHECK: G_BRCOND [[TST]], %[[TRUE]] +; CHECK: [[TST:%.*]](s1) = G_LOAD [[ADDR]](p0) +; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]] ; CHECK: G_BR %[[FALSE]] ; ; Check that each successor contains the return instruction. @@ -269,8 +269,8 @@ define void @trunc(i64 %a) { ; CHECK-LABEL: name: load ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 ; CHECK: [[ADDR42:%[0-9]+]](p42) = COPY %x1 -; CHECK: [[VAL1:%[0-9]+]](s64) = G_LOAD [[ADDR]] :: (load 8 from %ir.addr, align 16) -; CHECK: [[VAL2:%[0-9]+]](s64) = G_LOAD [[ADDR42]] :: (load 8 from %ir.addr42) +; CHECK: [[VAL1:%[0-9]+]](s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16) +; CHECK: [[VAL2:%[0-9]+]](s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42) ; CHECK: [[SUM:%.*]](s64) = G_ADD [[VAL1]], [[VAL2]] ; CHECK: %x0 = COPY [[SUM]] ; CHECK: RET_ReallyLR implicit %x0 @@ -286,8 +286,8 @@ define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) { ; CHECK: [[ADDR42:%[0-9]+]](p42) = COPY %x1 ; CHECK: [[VAL1:%[0-9]+]](s64) = COPY %x2 ; CHECK: [[VAL2:%[0-9]+]](s64) = COPY %x3 -; CHECK: G_STORE [[VAL1]], [[ADDR]] :: (store 8 into %ir.addr, align 16) -; CHECK: G_STORE [[VAL2]], [[ADDR42]] :: (store 8 into %ir.addr42) +; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16) +; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42) ; CHECK: RET_ReallyLR define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) { store i64 %val1, i64* %addr, align 16 @@ -302,7 +302,7 @@ define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) ; CHECK: [[PTR:%[0-9]+]](p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0 ; CHECK: [[PTR_VEC:%[0-9]+]](p0) = G_FRAME_INDEX %stack.0.ptr.vec ; CHECK: [[VEC:%[0-9]+]](<8 x s8>) = G_LOAD [[PTR_VEC]] -; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]], [[VEC]], [[PTR]] +; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0) ; CHECK: RET_ReallyLR declare i8* @llvm.returnaddress(i32) declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*) @@ -325,7 +325,7 @@ define void @intrinsics(i32 %cur, i32 %bits) { ; CHECK: [[FALSE]]: ; CHECK: [[RES2:%[0-9]+]](s32) = G_LOAD -; CHECK: [[RES:%[0-9]+]](s32) = PHI [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]] +; CHECK: [[RES:%[0-9]+]](s32) = PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]] ; CHECK: %w0 = COPY [[RES]] define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) { br i1 %tst, label %true, label %false @@ -512,8 +512,8 @@ define i8* @test_constant_null() { ; CHECK-LABEL: name: test_struct_memops ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 -; CHECK: [[VAL:%[0-9]+]](s64) = G_LOAD [[ADDR]] :: (load 8 from %ir.addr, align 4) -; CHECK: G_STORE [[VAL]], [[ADDR]] :: (store 8 into %ir.addr, align 4) +; CHECK: [[VAL:%[0-9]+]](s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 4) +; CHECK: G_STORE [[VAL]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 4) define void @test_struct_memops({ i8, i32 }* %addr) { %val = load { i8, i32 }, { i8, i32 }* %addr store { i8, i32 } %val, { i8, i32 }* %addr @@ -522,8 +522,8 @@ define void @test_struct_memops({ i8, i32 }* %addr) { ; CHECK-LABEL: name: test_i1_memops ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 -; CHECK: [[VAL:%[0-9]+]](s1) = G_LOAD [[ADDR]] :: (load 1 from %ir.addr) -; CHECK: G_STORE [[VAL]], [[ADDR]] :: (store 1 into %ir.addr) +; CHECK: [[VAL:%[0-9]+]](s1) = G_LOAD [[ADDR]](p0) :: (load 1 from %ir.addr) +; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into %ir.addr) define void @test_i1_memops(i1* %addr) { %val = load i1, i1* %addr store i1 %val, i1* %addr @@ -534,8 +534,8 @@ define void @test_i1_memops(i1* %addr) { ; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0 ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 -; CHECK: [[TST:%[0-9]+]](s1) = G_ICMP intpred(ne), [[LHS]], [[RHS]] -; CHECK: G_STORE [[TST]], [[ADDR]] +; CHECK: [[TST:%[0-9]+]](s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]] +; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0) define void @int_comparison(i32 %a, i32 %b, i1* %addr) { %res = icmp ne i32 %a, %b store i1 %res, i1* %addr @@ -602,8 +602,8 @@ define float @test_frem(float %arg1, float %arg2) { ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SADDO [[LHS]], [[RHS]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[ADDR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -617,8 +617,8 @@ define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[ZERO:%[0-9]+]](s1) = G_CONSTANT 0 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_UADDE [[LHS]], [[RHS]], [[ZERO]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[ADDR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -629,10 +629,10 @@ define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { ; CHECK-LABEL: name: test_ssub_overflow ; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0 ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 -; CHECK: [[SUBR:%[0-9]+]](p0) = COPY %x2 +; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SSUBO [[LHS]], [[RHS]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[SUBR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -643,11 +643,11 @@ define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { ; CHECK-LABEL: name: test_usub_overflow ; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0 ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 -; CHECK: [[SUBR:%[0-9]+]](p0) = COPY %x2 +; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[ZERO:%[0-9]+]](s1) = G_CONSTANT 0 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_USUBE [[LHS]], [[RHS]], [[ZERO]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[SUBR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -660,8 +660,8 @@ define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) { ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SMULO [[LHS]], [[RHS]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[ADDR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -674,8 +674,8 @@ define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2 ; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_UMULO [[LHS]], [[RHS]] -; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32 -; CHECK: G_STORE [[RES]], [[ADDR]] +; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32 +; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0) declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs) @@ -685,7 +685,7 @@ define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { ; CHECK-LABEL: name: test_extractvalue ; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD -; CHECK: [[RES:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]], 64 +; CHECK: [[RES:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]](s128), 64 ; CHECK: %w0 = COPY [[RES]] %struct.nested = type {i8, { i8, i32 }, i32} define i32 @test_extractvalue(%struct.nested* %addr) { @@ -696,7 +696,7 @@ define i32 @test_extractvalue(%struct.nested* %addr) { ; CHECK-LABEL: name: test_extractvalue_agg ; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD -; CHECK: [[RES:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]], 32 +; CHECK: [[RES:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]](s128), 32 ; CHECK: G_STORE [[RES]] define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { %struct = load %struct.nested, %struct.nested* %addr @@ -708,8 +708,8 @@ define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { ; CHECK-LABEL: name: test_insertvalue ; CHECK: [[VAL:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD -; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[VAL]], 64 -; CHECK: G_STORE [[NEWSTRUCT]], +; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[VAL]](s32), 64 +; CHECK: G_STORE [[NEWSTRUCT]](s128), define void @test_insertvalue(%struct.nested* %addr, i32 %val) { %struct = load %struct.nested, %struct.nested* %addr %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1 @@ -720,8 +720,8 @@ define void @test_insertvalue(%struct.nested* %addr, i32 %val) { ; CHECK-LABEL: name: test_insertvalue_agg ; CHECK: [[SMALLSTRUCT:%[0-9]+]](s64) = G_LOAD ; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD -; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[SMALLSTRUCT]], 32 -; CHECK: G_STORE [[RES]] +; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[SMALLSTRUCT]](s64), 32 +; CHECK: G_STORE [[RES]](s128) define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { %smallstruct = load {i8, i32}, {i8, i32}* %addr2 %struct = load %struct.nested, %struct.nested* %addr @@ -734,7 +734,7 @@ define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) { ; CHECK: [[TST:%[0-9]+]](s1) = COPY %w0 ; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w1 ; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w2 -; CHECK: [[RES:%[0-9]+]](s32) = G_SELECT [[TST]], [[LHS]], [[RHS]] +; CHECK: [[RES:%[0-9]+]](s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]] ; CHECK: %w0 = COPY [[RES]] define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) { %res = select i1 %tst, i32 %lhs, i32 %rhs @@ -743,8 +743,8 @@ define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) { ; CHECK-LABEL: name: test_fptosi ; CHECK: [[FPADDR:%[0-9]+]](p0) = COPY %x0 -; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]] -; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOSI [[FP]] +; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]](p0) +; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOSI [[FP]](s32) ; CHECK: %x0 = COPY [[RES]] define i64 @test_fptosi(float* %fp.addr) { %fp = load float, float* %fp.addr @@ -754,8 +754,8 @@ define i64 @test_fptosi(float* %fp.addr) { ; CHECK-LABEL: name: test_fptoui ; CHECK: [[FPADDR:%[0-9]+]](p0) = COPY %x0 -; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]] -; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOUI [[FP]] +; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]](p0) +; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOUI [[FP]](s32) ; CHECK: %x0 = COPY [[RES]] define i64 @test_fptoui(float* %fp.addr) { %fp = load float, float* %fp.addr @@ -766,8 +766,8 @@ define i64 @test_fptoui(float* %fp.addr) { ; CHECK-LABEL: name: test_sitofp ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 ; CHECK: [[IN:%[0-9]+]](s32) = COPY %w1 -; CHECK: [[FP:%[0-9]+]](s64) = G_SITOFP [[IN]] -; CHECK: G_STORE [[FP]], [[ADDR]] +; CHECK: [[FP:%[0-9]+]](s64) = G_SITOFP [[IN]](s32) +; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0) define void @test_sitofp(double* %addr, i32 %in) { %fp = sitofp i32 %in to double store double %fp, double* %addr @@ -777,8 +777,8 @@ define void @test_sitofp(double* %addr, i32 %in) { ; CHECK-LABEL: name: test_uitofp ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 ; CHECK: [[IN:%[0-9]+]](s32) = COPY %w1 -; CHECK: [[FP:%[0-9]+]](s64) = G_UITOFP [[IN]] -; CHECK: G_STORE [[FP]], [[ADDR]] +; CHECK: [[FP:%[0-9]+]](s64) = G_UITOFP [[IN]](s32) +; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0) define void @test_uitofp(double* %addr, i32 %in) { %fp = uitofp i32 %in to double store double %fp, double* %addr @@ -787,7 +787,7 @@ define void @test_uitofp(double* %addr, i32 %in) { ; CHECK-LABEL: name: test_fpext ; CHECK: [[IN:%[0-9]+]](s32) = COPY %s0 -; CHECK: [[RES:%[0-9]+]](s64) = G_FPEXT [[IN]] +; CHECK: [[RES:%[0-9]+]](s64) = G_FPEXT [[IN]](s32) ; CHECK: %d0 = COPY [[RES]] define double @test_fpext(float %in) { %res = fpext float %in to double @@ -796,7 +796,7 @@ define double @test_fpext(float %in) { ; CHECK-LABEL: name: test_fptrunc ; CHECK: [[IN:%[0-9]+]](s64) = COPY %d0 -; CHECK: [[RES:%[0-9]+]](s32) = G_FPTRUNC [[IN]] +; CHECK: [[RES:%[0-9]+]](s32) = G_FPTRUNC [[IN]](s64) ; CHECK: %s0 = COPY [[RES]] define float @test_fptrunc(double %in) { %res = fptrunc double %in to float @@ -806,7 +806,7 @@ define float @test_fptrunc(double %in) { ; CHECK-LABEL: name: test_constant_float ; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0 ; CHECK: [[TMP:%[0-9]+]](s32) = G_FCONSTANT float 1.500000e+00 -; CHECK: G_STORE [[TMP]], [[ADDR]] +; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0) define void @test_constant_float(float* %addr) { store float 1.5, float* %addr ret void @@ -816,10 +816,10 @@ define void @test_constant_float(float* %addr) { ; CHECK: [[LHSADDR:%[0-9]+]](p0) = COPY %x0 ; CHECK: [[RHSADDR:%[0-9]+]](p0) = COPY %x1 ; CHECK: [[BOOLADDR:%[0-9]+]](p0) = COPY %x2 -; CHECK: [[LHS:%[0-9]+]](s32) = G_LOAD [[LHSADDR]] -; CHECK: [[RHS:%[0-9]+]](s32) = G_LOAD [[RHSADDR]] -; CHECK: [[TST:%[0-9]+]](s1) = G_FCMP floatpred(oge), [[LHS]], [[RHS]] -; CHECK: G_STORE [[TST]], [[BOOLADDR]] +; CHECK: [[LHS:%[0-9]+]](s32) = G_LOAD [[LHSADDR]](p0) +; CHECK: [[RHS:%[0-9]+]](s32) = G_LOAD [[RHSADDR]](p0) +; CHECK: [[TST:%[0-9]+]](s1) = G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]] +; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0) define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) { %a = load float, float* %a.addr %b = load float, float* %b.addr diff --git a/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/test/CodeGen/AArch64/GlobalISel/call-translator.ll index 81ef3b37301..5afd47ddc75 100644 --- a/test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ b/test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -32,7 +32,7 @@ define void @test_simple_arg(i32 %in) { ; CHECK-LABEL: name: test_indirect_call ; CHECK: [[FUNC:%[0-9]+]](p0) = COPY %x0 -; CHECK: BLR [[FUNC]], csr_aarch64_aapcs, implicit-def %lr, implicit %sp +; CHECK: BLR [[FUNC]](p0), csr_aarch64_aapcs, implicit-def %lr, implicit %sp ; CHECK: RET_ReallyLR define void @test_indirect_call(void()* %func) { call void %func() diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir b/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir index 88e587fa79d..6c889ea2cb5 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-cmp.mir @@ -30,11 +30,11 @@ body: | %2(s8) = G_TRUNC %0 %3(s8) = G_TRUNC %1 - ; CHECK: %4(s1) = G_ICMP intpred(sge), %0, %1 + ; CHECK: %4(s1) = G_ICMP intpred(sge), %0(s64), %1 %4(s1) = G_ICMP intpred(sge), %0, %1 ; CHECK: [[LHS32:%[0-9]+]](s32) = G_ZEXT %2 ; CHECK: [[RHS32:%[0-9]+]](s32) = G_ZEXT %3 - ; CHECK: %8(s1) = G_ICMP intpred(ult), [[LHS32]], [[RHS32]] + ; CHECK: %8(s1) = G_ICMP intpred(ult), [[LHS32]](s32), [[RHS32]] %8(s1) = G_ICMP intpred(ult), %2, %3 ... diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir b/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir index 86bd82720be..8221325d952 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir @@ -48,11 +48,11 @@ body: | ; Only one of these extracts can be eliminated, the offsets don't match ; properly in the other cases. ; CHECK-LABEL: name: test_combines - ; CHECK: %3(s32) = G_SEQUENCE %2, 1 - ; CHECK: %4(s8) = G_EXTRACT %3, 0 + ; CHECK: %3(s32) = G_SEQUENCE %2(s8), 1 + ; CHECK: %4(s8) = G_EXTRACT %3(s32), 0 ; CHECK-NOT: G_EXTRACT - ; CHECK: %6(s8) = G_EXTRACT %3, 2 - ; CHECK: %7(s32) = G_ZEXT %2 + ; CHECK: %6(s8) = G_EXTRACT %3(s32), 2 + ; CHECK: %7(s32) = G_ZEXT %2(s8) %3(s32) = G_SEQUENCE %2, 1 %4(s8) = G_EXTRACT %3, 0 %5(s8) = G_EXTRACT %3, 1 @@ -60,9 +60,9 @@ body: | %7(s32) = G_ZEXT %5 ; Similarly, here the types don't match. - ; CHECK: %10(s32) = G_SEQUENCE %8, 0, %9, 16 - ; CHECK: %11(s1) = G_EXTRACT %10, 0 - ; CHECK: %12(s32) = G_EXTRACT %10, 0 + ; CHECK: %10(s32) = G_SEQUENCE %8(s16), 0, %9(s16), 16 + ; CHECK: %11(s1) = G_EXTRACT %10(s32), 0 + ; CHECK: %12(s32) = G_EXTRACT %10(s32), 0 %8(s16) = G_TRUNC %0 %9(s16) = G_ADD %8, %8 %10(s32) = G_SEQUENCE %8, 0, %9, 16 @@ -74,7 +74,7 @@ body: | %13(s16), %14(s16) = G_EXTRACT %10, 0, 16 %15(s16) = G_ADD %13, %14 - ; CHECK: %18(<2 x s32>) = G_EXTRACT %17, 0 + ; CHECK: %18(<2 x s32>) = G_EXTRACT %17(s128), 0 ; CHECK: %19(<2 x s32>) = G_ADD %18, %18 %16(s64) = COPY %x0 %17(s128) = G_SEQUENCE %16, 0, %16, 64 diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir b/test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir index 7218ff8625c..e051b8e6b20 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-fcmp.mir @@ -27,9 +27,9 @@ body: | %2(s32) = G_TRUNC %0 %3(s32) = G_TRUNC %1 - ; CHECK: %4(s1) = G_FCMP floatpred(oge), %0, %1 + ; CHECK: %4(s1) = G_FCMP floatpred(oge), %0(s64), %1 %4(s1) = G_FCMP floatpred(oge), %0, %1 - ; CHECK: %5(s1) = G_FCMP floatpred(uno), %2, %3 + ; CHECK: %5(s1) = G_FCMP floatpred(uno), %2(s32), %3 %5(s1) = G_FCMP floatpred(uno), %2, %3 ... diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir b/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir index c6d912980b1..bd7bbca7e51 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir @@ -28,20 +28,20 @@ body: | ; CHECK-LABEL: name: test_load %0(p0) = COPY %x0 - ; CHECK: [[BIT8:%[0-9]+]](s8) = G_LOAD %0 :: (load 1 from %ir.addr) + ; CHECK: [[BIT8:%[0-9]+]](s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr) ; CHECK: %1(s1) = G_TRUNC [[BIT8]] %1(s1) = G_LOAD %0 :: (load 1 from %ir.addr) - ; CHECK: %2(s8) = G_LOAD %0 :: (load 1 from %ir.addr) + ; CHECK: %2(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr) %2(s8) = G_LOAD %0 :: (load 1 from %ir.addr) - ; CHECK: %3(s16) = G_LOAD %0 :: (load 2 from %ir.addr) + ; CHECK: %3(s16) = G_LOAD %0(p0) :: (load 2 from %ir.addr) %3(s16) = G_LOAD %0 :: (load 2 from %ir.addr) - ; CHECK: %4(s32) = G_LOAD %0 :: (load 4 from %ir.addr) + ; CHECK: %4(s32) = G_LOAD %0(p0) :: (load 4 from %ir.addr) %4(s32) = G_LOAD %0 :: (load 4 from %ir.addr) - ; CHECK: %5(s64) = G_LOAD %0 :: (load 8 from %ir.addr) + ; CHECK: %5(s64) = G_LOAD %0(p0) :: (load 8 from %ir.addr) %5(s64) = G_LOAD %0 :: (load 8 from %ir.addr) ... @@ -62,23 +62,23 @@ body: | %0(p0) = COPY %x0 %1(s32) = COPY %w1 - ; CHECK: [[BIT8:%[0-9]+]](s8) = G_ANYEXT %2 - ; CHECK: G_STORE [[BIT8]], %0 :: (store 1 into %ir.addr) + ; CHECK: [[BIT8:%[0-9]+]](s8) = G_ANYEXT %2(s1) + ; CHECK: G_STORE [[BIT8]](s8), %0(p0) :: (store 1 into %ir.addr) %2(s1) = G_TRUNC %1 G_STORE %2, %0 :: (store 1 into %ir.addr) - ; CHECK: G_STORE %3, %0 :: (store 1 into %ir.addr) + ; CHECK: G_STORE %3(s8), %0(p0) :: (store 1 into %ir.addr) %3(s8) = G_TRUNC %1 G_STORE %3, %0 :: (store 1 into %ir.addr) - ; CHECK: G_STORE %4, %0 :: (store 2 into %ir.addr) + ; CHECK: G_STORE %4(s16), %0(p0) :: (store 2 into %ir.addr) %4(s16) = G_TRUNC %1 G_STORE %4, %0 :: (store 2 into %ir.addr) - ; CHECK: G_STORE %1, %0 :: (store 4 into %ir.addr) + ; CHECK: G_STORE %1(s32), %0(p0) :: (store 4 into %ir.addr) G_STORE %1, %0 :: (store 4 into %ir.addr) - ; CHECK: G_STORE %5, %0 :: (store 8 into %ir.addr) - %5(s64) = G_PTRTOINT %0 + ; CHECK: G_STORE %5(s64), %0(p0) :: (store 8 into %ir.addr) + %5(s64) = G_PTRTOINT %0(p0) G_STORE %5, %0 :: (store 8 into %ir.addr) ... diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-simple.mir b/test/CodeGen/AArch64/GlobalISel/legalize-simple.mir index c4b41dea776..499d800cd10 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-simple.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-simple.mir @@ -56,7 +56,7 @@ body: | %2(s64) = G_PTRTOINT %1 ; CHECK: [[TST32:%[0-9]+]](s32) = G_ANYEXT %3 - ; CHECK: G_BRCOND [[TST32]], %bb.1.next + ; CHECK: G_BRCOND [[TST32]](s32), %bb.1.next %3(s1) = G_TRUNC %0 G_BRCOND %3, %bb.1.next @@ -107,11 +107,11 @@ body: | %23(s64) = G_UITOFP %4 %24(s64) = G_SITOFP %0 - ; CHECK: %25(s1) = G_SELECT %10, %10, %5 - ; CHECK: %26(s8) = G_SELECT %10, %6, %11 - ; CHECK: %27(s16) = G_SELECT %10, %12, %7 - ; CHECK: %28(s32) = G_SELECT %10, %15, %16 - ; CHECK: %29(s64) = G_SELECT %10, %9, %24 + ; CHECK: %25(s1) = G_SELECT %10(s1), %10, %5 + ; CHECK: %26(s8) = G_SELECT %10(s1), %6, %11 + ; CHECK: %27(s16) = G_SELECT %10(s1), %12, %7 + ; CHECK: %28(s32) = G_SELECT %10(s1), %15, %16 + ; CHECK: %29(s64) = G_SELECT %10(s1), %9, %24 %25(s1) = G_SELECT %10, %10, %5 %26(s8) = G_SELECT %10, %6, %11 %27(s16) = G_SELECT %10, %12, %7 diff --git a/test/CodeGen/MIR/X86/expected-integer-after-tied-def.mir b/test/CodeGen/MIR/X86/expected-integer-after-tied-def.mir index a5c7b48e96c..edbe7d4c34e 100644 --- a/test/CodeGen/MIR/X86/expected-integer-after-tied-def.mir +++ b/test/CodeGen/MIR/X86/expected-integer-after-tied-def.mir @@ -17,7 +17,7 @@ body: | bb.0.entry: liveins: %rdi - ; CHECK: [[@LINE+1]]:78: expected an integer literal after 'tied-def' + ; CHECK: [[@LINE+1]]:78: expected tied-def or low-level type after '(' INLINEASM $"$foo", 1, 2818058, def %rdi, 2147483657, killed %rdi(tied-def) %rax = COPY killed %rdi RETQ killed %rax diff --git a/test/CodeGen/MIR/X86/expected-tied-def-after-lparen.mir b/test/CodeGen/MIR/X86/expected-tied-def-after-lparen.mir index fce8c1afa30..f80dd8d7e62 100644 --- a/test/CodeGen/MIR/X86/expected-tied-def-after-lparen.mir +++ b/test/CodeGen/MIR/X86/expected-tied-def-after-lparen.mir @@ -17,7 +17,7 @@ body: | bb.0.entry: liveins: %rdi - ; CHECK: [[@LINE+1]]:70: expected 'tied-def' after '(' + ; CHECK: [[@LINE+1]]:70: expected tied-def or low-level type after '(' INLINEASM $"$foo", 1, 2818058, def %rdi, 2147483657, killed %rdi(3) %rax = COPY killed %rdi RETQ killed %rax