1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s 3 4; A test for asm-goto output 5 6define i32 @test1(i32 %x) { 7; CHECK-LABEL: test1: 8; CHECK: # %bb.0: # %entry 9; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 10; CHECK-NEXT: addl $4, %eax 11; CHECK-NEXT: #APP 12; CHECK-NEXT: xorl %eax, %eax 13; CHECK-NEXT: jmp .Ltmp0 14; CHECK-NEXT: #NO_APP 15; CHECK-NEXT: # %bb.1: # %normal 16; CHECK-NEXT: retl 17; CHECK-NEXT: .Ltmp0: # Block address taken 18; CHECK-NEXT: .LBB0_2: # %abnormal 19; CHECK-NEXT: movl $1, %eax 20; CHECK-NEXT: retl 21entry: 22 %add = add nsw i32 %x, 4 23 %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal)) 24 to label %normal [label %abnormal] 25 26normal: 27 ret i32 %ret 28 29abnormal: 30 ret i32 1 31} 32 33define i32 @test2(i32 %out1, i32 %out2) { 34; CHECK-LABEL: test2: 35; CHECK: # %bb.0: # %entry 36; CHECK-NEXT: pushl %edi 37; CHECK-NEXT: .cfi_def_cfa_offset 8 38; CHECK-NEXT: pushl %esi 39; CHECK-NEXT: .cfi_def_cfa_offset 12 40; CHECK-NEXT: .cfi_offset %esi, -12 41; CHECK-NEXT: .cfi_offset %edi, -8 42; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edi 43; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi 44; CHECK-NEXT: movl $-1, %eax 45; CHECK-NEXT: cmpl %edi, %esi 46; CHECK-NEXT: jge .LBB1_2 47; CHECK-NEXT: # %bb.1: # %if.then 48; CHECK-NEXT: #APP 49; CHECK-NEXT: testl %esi, %esi 50; CHECK-NEXT: testl %edi, %esi 51; CHECK-NEXT: jne .Ltmp1 52; CHECK-NEXT: #NO_APP 53; CHECK-NEXT: jmp .LBB1_3 54; CHECK-NEXT: .LBB1_2: # %if.else 55; CHECK-NEXT: #APP 56; CHECK-NEXT: testl %esi, %edi 57; CHECK-NEXT: testl %esi, %edi 58; CHECK-NEXT: jne .Ltmp2 59; CHECK-NEXT: #NO_APP 60; CHECK-NEXT: .LBB1_3: 61; CHECK-NEXT: movl %esi, %eax 62; CHECK-NEXT: addl %edi, %eax 63; CHECK-NEXT: .Ltmp2: # Block address taken 64; CHECK-NEXT: .LBB1_5: # %return 65; CHECK-NEXT: popl %esi 66; CHECK-NEXT: .cfi_def_cfa_offset 8 67; CHECK-NEXT: popl %edi 68; CHECK-NEXT: .cfi_def_cfa_offset 4 69; CHECK-NEXT: retl 70; CHECK-NEXT: .Ltmp1: # Block address taken 71; CHECK-NEXT: .LBB1_4: # %label_true 72; CHECK-NEXT: .cfi_def_cfa_offset 12 73; CHECK-NEXT: movl $-2, %eax 74; CHECK-NEXT: jmp .LBB1_5 75entry: 76 %cmp = icmp slt i32 %out1, %out2 77 br i1 %cmp, label %if.then, label %if.else 78 79if.then: ; preds = %entry 80 %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "={si},={di},r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2) 81 to label %if.end [label %label_true, label %return] 82 83if.else: ; preds = %entry 84 %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "={si},={di},r,r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i32 %out2, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2) 85 to label %if.end [label %label_true, label %return] 86 87if.end: ; preds = %if.else, %if.then 88 %.sink11 = phi { i32, i32 } [ %0, %if.then ], [ %1, %if.else ] 89 %asmresult3 = extractvalue { i32, i32 } %.sink11, 0 90 %asmresult4 = extractvalue { i32, i32 } %.sink11, 1 91 %add = add nsw i32 %asmresult4, %asmresult3 92 br label %return 93 94label_true: ; preds = %if.else, %if.then 95 br label %return 96 97return: ; preds = %if.then, %if.else, %label_true, %if.end 98 %retval.0 = phi i32 [ %add, %if.end ], [ -2, %label_true ], [ -1, %if.else ], [ -1, %if.then ] 99 ret i32 %retval.0 100} 101 102define i32 @test3(i1 %cmp) { 103; CHECK-LABEL: test3: 104; CHECK: # %bb.0: # %entry 105; CHECK-NEXT: pushl %edi 106; CHECK-NEXT: .cfi_def_cfa_offset 8 107; CHECK-NEXT: pushl %esi 108; CHECK-NEXT: .cfi_def_cfa_offset 12 109; CHECK-NEXT: .cfi_offset %esi, -12 110; CHECK-NEXT: .cfi_offset %edi, -8 111; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) 112; CHECK-NEXT: je .LBB2_3 113; CHECK-NEXT: # %bb.1: # %true 114; CHECK-NEXT: #APP 115; CHECK-NEXT: .short %esi 116; CHECK-NEXT: .short %edi 117; CHECK-NEXT: #NO_APP 118; CHECK-NEXT: # %bb.2: 119; CHECK-NEXT: movl %edi, %eax 120; CHECK-NEXT: jmp .LBB2_5 121; CHECK-NEXT: .LBB2_3: # %false 122; CHECK-NEXT: #APP 123; CHECK-NEXT: .short %eax 124; CHECK-NEXT: .short %edx 125; CHECK-NEXT: #NO_APP 126; CHECK-NEXT: # %bb.4: 127; CHECK-NEXT: movl %edx, %eax 128; CHECK-NEXT: .LBB2_5: # %asm.fallthrough 129; CHECK-NEXT: popl %esi 130; CHECK-NEXT: .cfi_def_cfa_offset 8 131; CHECK-NEXT: popl %edi 132; CHECK-NEXT: .cfi_def_cfa_offset 4 133; CHECK-NEXT: retl 134; CHECK-NEXT: .Ltmp3: # Block address taken 135; CHECK-NEXT: .LBB2_6: # %indirect 136; CHECK-NEXT: .cfi_def_cfa_offset 12 137; CHECK-NEXT: movl $42, %eax 138; CHECK-NEXT: jmp .LBB2_5 139entry: 140 br i1 %cmp, label %true, label %false 141 142true: 143 %0 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={si},={di},X" (i8* blockaddress(@test3, %indirect)) to label %asm.fallthrough [label %indirect] 144 145false: 146 %1 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={ax},={dx},X" (i8* blockaddress(@test3, %indirect)) to label %asm.fallthrough [label %indirect] 147 148asm.fallthrough: 149 %vals = phi { i32, i32 } [ %0, %true ], [ %1, %false ] 150 %v = extractvalue { i32, i32 } %vals, 1 151 ret i32 %v 152 153indirect: 154 ret i32 42 155} 156 157; Test 4 - asm-goto with output constraints. 158define i32 @test4(i32 %out1, i32 %out2) { 159; CHECK-LABEL: test4: 160; CHECK: # %bb.0: # %entry 161; CHECK-NEXT: movl $-1, %eax 162; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 163; CHECK-NEXT: #APP 164; CHECK-NEXT: testl %ecx, %ecx 165; CHECK-NEXT: testl %edx, %ecx 166; CHECK-NEXT: jne .Ltmp4 167; CHECK-NEXT: #NO_APP 168; CHECK-NEXT: # %bb.1: # %asm.fallthrough 169; CHECK-NEXT: #APP 170; CHECK-NEXT: testl %ecx, %edx 171; CHECK-NEXT: testl %ecx, %edx 172; CHECK-NEXT: jne .Ltmp5 173; CHECK-NEXT: #NO_APP 174; CHECK-NEXT: # %bb.2: # %asm.fallthrough2 175; CHECK-NEXT: addl %edx, %ecx 176; CHECK-NEXT: movl %ecx, %eax 177; CHECK-NEXT: retl 178; CHECK-NEXT: .Ltmp4: # Block address taken 179; CHECK-NEXT: .LBB3_3: # %label_true 180; CHECK-NEXT: movl $-2, %eax 181; CHECK-NEXT: .Ltmp5: # Block address taken 182; CHECK-NEXT: .LBB3_4: # %return 183; CHECK-NEXT: retl 184entry: 185 %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return)) 186 to label %asm.fallthrough [label %label_true, label %return] 187 188asm.fallthrough: ; preds = %entry 189 %asmresult = extractvalue { i32, i32 } %0, 0 190 %asmresult1 = extractvalue { i32, i32 } %0, 1 191 %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %asmresult, i32 %asmresult1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return)) 192 to label %asm.fallthrough2 [label %label_true, label %return] 193 194asm.fallthrough2: ; preds = %asm.fallthrough 195 %asmresult3 = extractvalue { i32, i32 } %1, 0 196 %asmresult4 = extractvalue { i32, i32 } %1, 1 197 %add = add nsw i32 %asmresult3, %asmresult4 198 br label %return 199 200label_true: ; preds = %asm.fallthrough, %entry 201 br label %return 202 203return: ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2 204 %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ] 205 ret i32 %retval.0 206} 207