1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2; FIXME(ndesaulniers): get this test to pass with -verify-machineinstrs 3; enabled. https://github.com/llvm/llvm-project/issues/60827 4; RUN: llc -mtriple=i386-linux-gnu %s -o - -stop-after=finalize-isel \ 5; RUN: -verify-machineinstrs=0 -start-before=x86-isel | FileCheck %s 6 7define i8 @emulator_cmpxchg_emulated() { 8 ; CHECK-LABEL: name: emulator_cmpxchg_emulated 9 ; CHECK: bb.0.entry: 10 ; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000) 11 ; CHECK-NEXT: {{ $}} 12 ; CHECK-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm $noreg, 1, $noreg, 0, $noreg :: (load (s32) from `ptr null`, align 8) 13 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32_norex2 = COPY [[MOV32rm]] 14 ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2686986 /* regdef:GR32_NOREX2 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[COPY]](tied-def 5), 13 /* imm */, %bb.2 15 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $eflags 16 ; CHECK-NEXT: $eflags = COPY [[COPY1]] 17 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags 18 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY %3 19 ; CHECK-NEXT: JMP_1 %bb.1 20 ; CHECK-NEXT: {{ $}} 21 ; CHECK-NEXT: bb.1.asm.fallthrough: 22 ; CHECK-NEXT: $al = COPY [[SETCCr]] 23 ; CHECK-NEXT: RET 0, $al 24 ; CHECK-NEXT: {{ $}} 25 ; CHECK-NEXT: bb.2.efaultu64.split (machine-block-address-taken, inlineasm-br-indirect-target): 26 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags 27 ; CHECK-NEXT: $al = COPY [[SETCCr1]] 28 ; CHECK-NEXT: RET 0, $al 29entry: 30 %0 = load i32, ptr null, align 8 31 %1 = callbr { i8, i32 } asm "", "={@ccz},=r,1,!i"(i32 %0) 32 to label %asm.fallthrough [label %efaultu64.split] 33 34asm.fallthrough: 35 %asmresult = extractvalue { i8, i32 } %1, 0 36 %asmresult1 = extractvalue { i8, i32 } %1, 1 37 ret i8 %asmresult 38 39efaultu64.split: 40 %2 = call { i8, i32 } @llvm.callbr.landingpad.sl_i8i32s({ i8, i32 } %1) 41 %asmresult2 = extractvalue { i8, i32 } %2, 0 42 %asmresult3 = extractvalue { i8, i32 } %2, 1 43 ret i8 %asmresult2 44} 45 46; Same test but return second value 47define i32 @emulator_cmpxchg_emulated2() { 48 ; CHECK-LABEL: name: emulator_cmpxchg_emulated2 49 ; CHECK: bb.0.entry: 50 ; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000) 51 ; CHECK-NEXT: {{ $}} 52 ; CHECK-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm $noreg, 1, $noreg, 0, $noreg :: (load (s32) from `ptr null`, align 8) 53 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32_norex2 = COPY [[MOV32rm]] 54 ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2686986 /* regdef:GR32_NOREX2 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[COPY]](tied-def 5), 13 /* imm */, %bb.2 55 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $eflags 56 ; CHECK-NEXT: $eflags = COPY [[COPY1]] 57 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags 58 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY %3 59 ; CHECK-NEXT: JMP_1 %bb.1 60 ; CHECK-NEXT: {{ $}} 61 ; CHECK-NEXT: bb.1.asm.fallthrough: 62 ; CHECK-NEXT: $eax = COPY [[COPY2]] 63 ; CHECK-NEXT: RET 0, $eax 64 ; CHECK-NEXT: {{ $}} 65 ; CHECK-NEXT: bb.2.efaultu64.split (machine-block-address-taken, inlineasm-br-indirect-target): 66 ; CHECK-NEXT: $eax = COPY %3 67 ; CHECK-NEXT: RET 0, $eax 68entry: 69 %0 = load i32, ptr null, align 8 70 %1 = callbr { i8, i32 } asm "", "={@ccz},=r,1,!i"(i32 %0) 71 to label %asm.fallthrough [label %efaultu64.split] 72 73asm.fallthrough: 74 %asmresult = extractvalue { i8, i32 } %1, 0 75 %asmresult1 = extractvalue { i8, i32 } %1, 1 76 ret i32 %asmresult1 77 78efaultu64.split: 79 %2 = call { i8, i32 } @llvm.callbr.landingpad.sl_i8i32s({ i8, i32 } %1) 80 %asmresult2 = extractvalue { i8, i32 } %2, 0 81 %asmresult3 = extractvalue { i8, i32 } %2, 1 82 ret i32 %asmresult3 83} 84 85define i64 @multireg() { 86 ; CHECK-LABEL: name: multireg 87 ; CHECK: bb.0.entry: 88 ; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000) 89 ; CHECK-NEXT: {{ $}} 90 ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 18 /* regdef */, implicit-def $eax, implicit-def $edx, 13 /* imm */, %bb.2 91 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eax 92 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edx 93 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[COPY1]] 94 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr32 = COPY [[COPY]] 95 ; CHECK-NEXT: JMP_1 %bb.1 96 ; CHECK-NEXT: {{ $}} 97 ; CHECK-NEXT: bb.1.ft: 98 ; CHECK-NEXT: $eax = COPY [[COPY3]] 99 ; CHECK-NEXT: $edx = COPY [[COPY2]] 100 ; CHECK-NEXT: RET 0, $eax, $edx 101 ; CHECK-NEXT: {{ $}} 102 ; CHECK-NEXT: bb.2.split (machine-block-address-taken, inlineasm-br-indirect-target): 103 ; CHECK-NEXT: liveins: $eax, $edx 104 ; CHECK-NEXT: {{ $}} 105 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr32 = COPY $eax 106 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gr32 = COPY $edx 107 ; CHECK-NEXT: $eax = COPY [[COPY4]] 108 ; CHECK-NEXT: $edx = COPY [[COPY5]] 109 ; CHECK-NEXT: RET 0, $eax, $edx 110entry: 111 %0 = callbr i64 asm "", "=A,!i"() to label %ft [label %split] 112ft: 113 ret i64 %0 114split: 115 %1 = call i64 @llvm.callbr.landingpad.i64(i64 %0) 116 ret i64 %1 117} 118declare i64 @llvm.callbr.landingpad.i64(i64) 119declare { i8, i32 } @llvm.callbr.landingpad.sl_i8i32s({ i8, i32 }) 120