diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll @@ -1,18 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s ; A test for asm-goto output -; CHECK-LABEL: test1: -; CHECK: movl 4(%esp), %eax -; CHECK-NEXT: addl $4, %eax -; CHECK-NEXT: #APP -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: jmp .Ltmp0 -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB0_1: -; CHECK-NEXT: retl -; CHECK-LABEL: .Ltmp0: # Address of block that was removed by CodeGen define i32 @test1(i32 %x) { +; CHECK-LABEL: test1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: addl $4, %eax +; CHECK-NEXT: #APP +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: jmp .Ltmp0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB0_1: # %normal +; CHECK-NEXT: retl +; CHECK-NEXT: .Ltmp0: # Block address taken +; CHECK-NEXT: .LBB0_2: # %abnormal +; CHECK-NEXT: movl $1, %eax +; CHECK-NEXT: retl entry: %add = add nsw i32 %x, 4 %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal)) @@ -25,28 +30,49 @@ ret i32 1 } +define i32 @test2(i32 %out1, i32 %out2) { ; CHECK-LABEL: test2: -; CHECK: # %bb.1: # %if.then -; CHECK-NEXT: #APP -; CHECK-NEXT: testl %esi, %esi -; CHECK-NEXT: testl %edi, %esi -; CHECK-NEXT: jne .Ltmp1 -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB1_2: -; CHECK-NEXT: jmp .LBB1_4 +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %edi +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: pushl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 12 +; CHECK-NEXT: .cfi_offset %esi, -12 +; CHECK-NEXT: .cfi_offset %edi, -8 +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edi +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi +; CHECK-NEXT: movl $-1, %eax +; CHECK-NEXT: cmpl %edi, %esi +; CHECK-NEXT: jge .LBB1_3 +; CHECK-NEXT: # %bb.1: # %if.then +; CHECK-NEXT: #APP +; CHECK-NEXT: testl %esi, %esi +; CHECK-NEXT: testl %edi, %esi +; CHECK-NEXT: jne .Ltmp1 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB1_2: # %if.then +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: addl %esi, %eax +; CHECK-NEXT: .Ltmp2: # Block address taken +; CHECK-NEXT: .LBB1_6: # %return +; CHECK-NEXT: popl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: popl %edi +; CHECK-NEXT: .cfi_def_cfa_offset 4 +; CHECK-NEXT: retl ; CHECK-NEXT: .LBB1_3: # %if.else -; CHECK-NEXT: #APP -; CHECK-NEXT: testl %esi, %edi -; CHECK-NEXT: testl %esi, %edi -; CHECK-NEXT: jne .Ltmp2 -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB1_4: -; CHECK-NEXT: movl %esi, %eax -; CHECK-NEXT: addl %edi, %eax -; CHECK-NEXT: .Ltmp2: -; CHECK-NEXT: # %bb.5: # %return -; CHECK-LABEL: .Ltmp1: # Address of block that was removed by CodeGen -define i32 @test2(i32 %out1, i32 %out2) { +; CHECK-NEXT: .cfi_def_cfa_offset 12 +; CHECK-NEXT: #APP +; CHECK-NEXT: testl %esi, %edi +; CHECK-NEXT: testl %esi, %edi +; CHECK-NEXT: jne .Ltmp2 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB1_4: # %if.else +; CHECK-NEXT: jmp .LBB1_2 +; CHECK-NEXT: .Ltmp1: # Block address taken +; CHECK-NEXT: .LBB1_5: # %label_true +; CHECK-NEXT: movl $-2, %eax +; CHECK-NEXT: jmp .LBB1_6 entry: %cmp = icmp slt i32 %out1, %out2 br i1 %cmp, label %if.then, label %if.else @@ -74,25 +100,43 @@ ret i32 %retval.0 } +define i32 @test3(i1 %cmp) { ; CHECK-LABEL: test3: -; CHECK: # %bb.1: # %true -; CHECK-NEXT: #APP -; CHECK-NEXT: .short %esi -; CHECK-NEXT: .short %edi -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB2_2: -; CHECK-NEXT: movl %edi, %eax -; CHECK-NEXT: jmp .LBB2_5 +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %edi +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: pushl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 12 +; CHECK-NEXT: .cfi_offset %esi, -12 +; CHECK-NEXT: .cfi_offset %edi, -8 +; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) +; CHECK-NEXT: je .LBB2_3 +; CHECK-NEXT: # %bb.1: # %true +; CHECK-NEXT: #APP +; CHECK-NEXT: .short %esi +; CHECK-NEXT: .short %edi +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB2_2: # %true +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: jmp .LBB2_5 ; CHECK-NEXT: .LBB2_3: # %false -; CHECK-NEXT: #APP -; CHECK-NEXT: .short %eax -; CHECK-NEXT: .short %edx -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB2_4: -; CHECK-NEXT: movl %edx, %eax +; CHECK-NEXT: #APP +; CHECK-NEXT: .short %eax +; CHECK-NEXT: .short %edx +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB2_4: # %false +; CHECK-NEXT: movl %edx, %eax ; CHECK-NEXT: .LBB2_5: # %asm.fallthrough -; CHECK-LABEL: .Ltmp3: # Address of block that was removed by CodeGen -define i32 @test3(i1 %cmp) { +; CHECK-NEXT: popl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: popl %edi +; CHECK-NEXT: .cfi_def_cfa_offset 4 +; CHECK-NEXT: retl +; CHECK-NEXT: .Ltmp3: # Block address taken +; CHECK-NEXT: .LBB2_6: # %indirect +; CHECK-NEXT: .cfi_def_cfa_offset 12 +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: jmp .LBB2_5 entry: br i1 %cmp, label %true, label %false @@ -112,29 +156,32 @@ } ; Test 4 - asm-goto with output constraints. +define i32 @test4(i32 %out1, i32 %out2) { ; CHECK-LABEL: test4: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movl $-1, %eax -; CHECK-NEXT: movl 4(%esp), %ecx -; CHECK-NEXT: #APP -; CHECK-NEXT: testl %ecx, %ecx -; CHECK-NEXT: testl %edx, %ecx -; CHECK-NEXT: jne .Ltmp4 -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB3_1: -; CHECK-NEXT: #APP -; CHECK-NEXT: testl %ecx, %edx -; CHECK-NEXT: testl %ecx, %edx -; CHECK-NEXT: jne .Ltmp5 -; CHECK-NEXT: #NO_APP -; CHECK-NEXT: .LBB3_2: -; CHECK-NEXT: addl %edx, %ecx -; CHECK-NEXT: movl %ecx, %eax -; CHECK-NEXT: .Ltmp5: -; CHECK-NEXT: # %bb.3: # %return -; CHECK-NEXT: retl -; CHECK-LABEL: .Ltmp4: # Address of block that was removed by CodeGen -define i32 @test4(i32 %out1, i32 %out2) { +; CHECK-NEXT: movl $-1, %eax +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: #APP +; CHECK-NEXT: testl %ecx, %ecx +; CHECK-NEXT: testl %edx, %ecx +; CHECK-NEXT: jne .Ltmp4 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB3_1: # %asm.fallthrough +; CHECK-NEXT: #APP +; CHECK-NEXT: testl %ecx, %edx +; CHECK-NEXT: testl %ecx, %edx +; CHECK-NEXT: jne .Ltmp5 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .LBB3_2: # %asm.fallthrough +; CHECK-NEXT: addl %edx, %ecx +; CHECK-NEXT: movl %ecx, %eax +; CHECK-NEXT: retl +; CHECK-NEXT: .Ltmp4: # Block address taken +; CHECK-NEXT: .LBB3_3: # %label_true +; CHECK-NEXT: movl $-2, %eax +; CHECK-NEXT: .Ltmp5: # Block address taken +; CHECK-NEXT: .LBB3_4: # %return +; CHECK-NEXT: retl entry: %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)) to label %asm.fallthrough [label %label_true, label %return]