llvm.org GIT mirror llvm / b75e864
Add some tests and update an existing test to reflect recent x86 isel peeps. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92509 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
3 changed file(s) with 105 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
None ; RUN: llc < %s -march=x86 -mcpu=yonah | grep {testl.*%e.x.*%e.x}
0 ; RUN: llc < %s -march=x86 -mcpu=yonah | FileCheck %s
11 ; rdar://5752025
22
3 ; We don't want to fold the and into the test, because the and clobbers its
4 ; input forcing a copy. We want:
5 ; movl $15, %ecx
6 ; andl 4(%esp), %ecx
7 ; testl %ecx, %ecx
3 ; We want:
4 ; CHECK: movl 4(%esp), %ecx
5 ; CHECK-NEXT: andl $15, %ecx
6 ; CHECK-NEXT: movl $42, %eax
7 ; CHECK-NEXT: cmovel %ecx, %eax
8 ; CHECK-NEXT: ret
9 ;
10 ; We don't want:
11 ; movl 4(%esp), %eax
12 ; movl %eax, %ecx # bad: extra copy
13 ; andl $15, %ecx
14 ; testl $15, %eax # bad: peep obstructed
815 ; movl $42, %eax
9 ; cmove %ecx, %eax
16 ; cmovel %ecx, %eax
1017 ; ret
1118 ;
12 ; Not:
13 ; movl 4(%esp), %eax
14 ; movl %eax, %ecx
19 ; We also don't want:
20 ; movl $15, %ecx # bad: larger encoding
21 ; andl 4(%esp), %ecx
22 ; movl $42, %eax
23 ; cmovel %ecx, %eax
24 ; ret
25 ;
26 ; We also don't want:
27 ; movl 4(%esp), %ecx
1528 ; andl $15, %ecx
16 ; testl $15, %eax
29 ; testl %ecx, %ecx # bad: unnecessary test
1730 ; movl $42, %eax
18 ; cmove %ecx, %eax
31 ; cmovel %ecx, %eax
1932 ; ret
2033
2134 define i32 @t1(i32 %X) nounwind {
0 ;; X's live range extends beyond the shift, so the register allocator
1 ;; cannot coalesce it with Y. Because of this, a copy needs to be
2 ;; emitted before the shift to save the register value before it is
3 ;; clobbered. However, this copy is not needed if the register
4 ;; allocator turns the shift into an LEA. This also occurs for ADD.
5
6 ; Check that the shift gets turned into an LEA.
7 ; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \
8 ; RUN: not grep {mov E.X, E.X}
9
10 @G = external global i32 ; [#uses=3]
11
12 define i32 @test1(i32 %X, i32 %Y) {
13 %Z = add i32 %X, %Y ; [#uses=1]
14 volatile store i32 %Y, i32* @G
15 volatile store i32 %Z, i32* @G
16 ret i32 %X
17 }
18
19 define i32 @test2(i32 %X) {
20 %Z = add i32 %X, 1 ; [#uses=1]
21 volatile store i32 %Z, i32* @G
22 ret i32 %X
23 }
0 ; RUN: llc < %s -march=x86-64 -o - | FileCheck %s
1
2 ; Reuse the flags value from the add instructions instead of emitting separate
3 ; testl instructions.
4
5 ; Use the flags on the add.
6
7 ; CHECK: add_zf:
8 ; CHECK: addl (%rdi), %esi
9 ; CHECK-NEXT: movl %edx, %eax
10 ; CHECK-NEXT: cmovnsl %ecx, %eax
11 ; CHECK-NEXT: ret
12
13 define i32 @add_zf(i32* %x, i32 %y, i32 %a, i32 %b) nounwind {
14 %tmp2 = load i32* %x, align 4 ; [#uses=1]
15 %tmp4 = add i32 %tmp2, %y ; [#uses=1]
16 %tmp5 = icmp slt i32 %tmp4, 0 ; [#uses=1]
17 %tmp.0 = select i1 %tmp5, i32 %a, i32 %b ; [#uses=1]
18 ret i32 %tmp.0
19 }
20
21 declare void @foo(i32)
22
23 ; Don't use the flags result of the and here, since the and has no
24 ; other use. A simple test is better.
25
26 ; CHECK: bar:
27 ; CHECK: testb $16, %dil
28
29 define void @bar(i32 %x) nounwind {
30 %y = and i32 %x, 16
31 %t = icmp eq i32 %y, 0
32 br i1 %t, label %true, label %false
33 true:
34 call void @foo(i32 %x)
35 ret void
36 false:
37 ret void
38 }
39
40 ; Do use the flags result of the and here, since the and has another use.
41
42 ; CHECK: qux:
43 ; CHECK: andl $16, %edi
44 ; CHECK-NEXT: jne .LBB3_2
45
46 define void @qux(i32 %x) nounwind {
47 %y = and i32 %x, 16
48 %t = icmp eq i32 %y, 0
49 br i1 %t, label %true, label %false
50 true:
51 call void @foo(i32 %y)
52 ret void
53 false:
54 ret void
55 }