diff --git a/llvm/docs/MIRLangRef.rst b/llvm/docs/MIRLangRef.rst --- a/llvm/docs/MIRLangRef.rst +++ b/llvm/docs/MIRLangRef.rst @@ -328,8 +328,9 @@ Miscellaneous Attributes ^^^^^^^^^^^^^^^^^^^^^^^^ -The attributes ``IsAddressTaken``, ``IsLandingPad`` and ``Alignment`` can be -specified in brackets after the block's definition: +The attributes ``IsAddressTaken``, ``IsLandingPad``, +``IsInlineAsmBrIndirectTarget`` and ``Alignment`` can be specified in brackets +after the block's definition: .. code-block:: text @@ -339,6 +340,8 @@ bb.3(landing-pad, align 4): + bb.4 (inlineasm-br-indirect-target): + .. TODO: Describe the way the reference to an unnamed LLVM IR block can be preserved. diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -116,6 +116,7 @@ kw_liveout, kw_address_taken, kw_landing_pad, + kw_inlineasm_br_indirect_target, kw_ehfunclet_entry, kw_liveins, kw_successors, diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -261,6 +261,8 @@ .Case("liveout", MIToken::kw_liveout) .Case("address-taken", MIToken::kw_address_taken) .Case("landing-pad", MIToken::kw_landing_pad) + .Case("inlineasm-br-indirect-target", + MIToken::kw_inlineasm_br_indirect_target) .Case("ehfunclet-entry", MIToken::kw_ehfunclet_entry) .Case("liveins", MIToken::kw_liveins) .Case("successors", MIToken::kw_successors) diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -674,6 +674,7 @@ lex(); bool HasAddressTaken = false; bool IsLandingPad = false; + bool IsInlineAsmBrIndirectTarget = false; bool IsEHFuncletEntry = false; Optional SectionID; uint64_t Alignment = 0; @@ -690,6 +691,10 @@ IsLandingPad = true; lex(); break; + case MIToken::kw_inlineasm_br_indirect_target: + IsInlineAsmBrIndirectTarget = true; + lex(); + break; case MIToken::kw_ehfunclet_entry: IsEHFuncletEntry = true; lex(); @@ -737,6 +742,7 @@ if (HasAddressTaken) MBB->setHasAddressTaken(); MBB->setIsEHPad(IsLandingPad); + MBB->setIsInlineAsmBrIndirectTarget(IsInlineAsmBrIndirectTarget); MBB->setIsEHFuncletEntry(IsEHFuncletEntry); if (SectionID.hasValue()) { MBB->setSectionID(SectionID.getValue()); diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -517,6 +517,11 @@ os << "landing-pad"; hasAttributes = true; } + if (isInlineAsmBrIndirectTarget()) { + os << (hasAttributes ? ", " : " ("); + os << "inlineasm-br-indirect-target"; + hasAttributes = true; + } if (isEHFuncletEntry()) { os << (hasAttributes ? ", " : " ("); os << "ehfunclet-entry"; diff --git a/llvm/test/CodeGen/X86/callbr-asm-kill.mir b/llvm/test/CodeGen/X86/callbr-asm-kill.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/callbr-asm-kill.mir @@ -0,0 +1,93 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs -O2 -run-pass=phi-node-elimination -o - %s | FileCheck %s + +--- | + ; ModuleID = '' + source_filename = "" + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + target triple = "x86_64-unknown-linux-gnu" + + declare void @foo(i8*) + + ; Function Attrs: nounwind + define void @test1(i8* %arg, i8** %mem) #0 { + entry: + br label %loop + + loop: ; preds = %loop, %entry + %a = phi i8* [ %arg, %entry ], [ %b, %loop ] + %b = load i8*, i8** %mem, align 8 + call void @foo(i8* %a) + callbr void asm sideeffect "", "*m,X"(i8* %b, i8* blockaddress(@test1, %loop)) + to label %end [label %loop] + + end: ; preds = %loop + ret void + } + + attributes #0 = { nounwind } + +... +--- +name: test1 +alignment: 16 +tracksRegLiveness: true +registers: + - { id: 0, class: gr64 } + - { id: 1, class: gr64 } + - { id: 2, class: gr64 } + - { id: 3, class: gr64 } +liveins: + - { reg: '$rdi', virtual-reg: '%2' } + - { reg: '$rsi', virtual-reg: '%3' } +frameInfo: + maxAlignment: 1 + hasCalls: true +machineFunctionInfo: {} +body: | + ; CHECK-LABEL: name: test1 + ; CHECK: bb.0.entry: + ; CHECK-NEXT: successors: %bb.1(0x80000000) + ; CHECK-NEXT: liveins: $rdi, $rsi + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY killed $rsi + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY killed $rdi + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY [[COPY1]] + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1.loop (address-taken, inlineasm-br-indirect-target): + ; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr64 = COPY [[COPY2]] + ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.mem) + ; CHECK-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + ; CHECK-NEXT: $rdi = COPY killed [[COPY3]] + ; CHECK-NEXT: CALL64pcrel32 target-flags(x86-plt) @foo, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit-def $rsp, implicit-def $ssp + ; CHECK-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr64 = COPY [[MOV64rm]] + ; CHECK-NEXT: INLINEASM_BR &"", 9 /* sideeffect mayload attdialect */, 196654 /* mem:m */, [[MOV64rm]], 1, $noreg, 0, $noreg, 13 /* imm */, blockaddress(@test1, %ir-block.loop) + ; CHECK-NEXT: JMP_1 %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.end: + ; CHECK-NEXT: RET 0 + bb.0.entry: + liveins: $rdi, $rsi + + %3:gr64 = COPY killed $rsi + %2:gr64 = COPY killed $rdi + + bb.1.loop (address-taken, inlineasm-br-indirect-target): + successors: %bb.2(0x80000000), %bb.1(0x00000000) + + %0:gr64 = PHI %2, %bb.0, %1, %bb.1 + %1:gr64 = MOV64rm %3, 1, $noreg, 0, $noreg :: (load (s64) from %ir.mem) + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $rdi = COPY killed %0 + CALL64pcrel32 target-flags(x86-plt) @foo, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + INLINEASM_BR &"", 9 /* sideeffect mayload attdialect */, 196654 /* mem:m */, %1, 1, $noreg, 0, $noreg, 13 /* imm */, blockaddress(@test1, %ir-block.loop) + JMP_1 %bb.2 + + bb.2.end: + RET 0 + +... diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll @@ -17,12 +17,12 @@ ; Check the second INLINEASM_BR target block is preceded by the block with the ; second INLINEASM_BR. -; CHECK: bb.2 (%ir-block.7, address-taken): +; CHECK: bb.2 (%ir-block.7, address-taken, inlineasm-br-indirect-target): ; CHECK-NEXT: predecessors: %bb.1 ; Check the first INLINEASM_BR target block is predecessed by the block with ; the first INLINEASM_BR. -; CHECK: bb.4 (%ir-block.11, address-taken): +; CHECK: bb.4 (%ir-block.11, address-taken, inlineasm-br-indirect-target): ; CHECK-NEXT: predecessors: %bb.0 @.str = private unnamed_addr constant [26 x i8] c"inline asm#1 returned %d\0A\00", align 1 diff --git a/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll --- a/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll +++ b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll @@ -30,7 +30,7 @@ ; CHECK: [[PHI:%[0-9]+]]:gr64 = PHI [[COPY]], %bb.2, [[MOV64rm]], %bb.1 ; CHECK: INLINEASM_BR &"#$0 $1 $2", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42, 13 /* imm */, 0, 13 /* imm */, blockaddress(@test1, %ir-block.bb17.i.i.i), 12 /* clobber */, implicit-def early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def early-clobber $eflags ; CHECK: JMP_1 %bb.5 - ; CHECK: bb.4.bb17.i.i.i (address-taken): + ; CHECK: bb.4.bb17.i.i.i (address-taken, inlineasm-br-indirect-target): ; CHECK: successors: %bb.5(0x80000000) ; CHECK: bb.5.kmem_cache_has_cpu_partial.exit: ; CHECK: $rax = COPY [[PHI]]