blob: d0a130a09d876ab5b7a91b8dd2f99690f85b7f0c [file] [log] [blame]
Jim Stichnothe5a5be72014-09-10 11:51:38 -07001; This tests some of the subtleties of Phi lowering. In particular,
2; it tests that it does the right thing when it tries to enable
3; compare/branch fusing.
4
Karl Schimpf2a5324a2014-09-25 09:37:49 -07005; TODO(kschimpf) Find out why lc2i must be used.
6; RUN: %lc2i -i %s --args -O2 --verbose none --no-phi-edge-split \
Jim Stichnothe5a5be72014-09-10 11:51:38 -07007; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
8; RUN: | llvm-objdump -d -symbolize -x86-asm-syntax=intel - | FileCheck %s
Karl Schimpf2a5324a2014-09-25 09:37:49 -07009; RUN: %lc2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s
10; RUN: %lc2i -i %s --insts | %szdiff %s | FileCheck --check-prefix=DUMP %s
Jim Stichnothe5a5be72014-09-10 11:51:38 -070011
12define internal i32 @testPhi1(i32 %arg) {
13entry:
14 %cmp1 = icmp sgt i32 %arg, 0
15 br i1 %cmp1, label %next, label %target
16next:
17 br label %target
18target:
19 %merge = phi i1 [ %cmp1, %entry ], [ false, %next ]
20 %result = zext i1 %merge to i32
21 ret i32 %result
22}
23; Test that compare/branch fusing does not happen, and Phi lowering is
24; put in the right place.
25; CHECK-LABEL: testPhi1
26; CHECK: cmp {{.*}}, 0
27; CHECK: mov {{.*}}, 1
28; CHECK: jg
29; CHECK: mov {{.*}}, 0
30; CHECK: mov [[PHI:.*]],
31; CHECK: cmp {{.*}}, 0
Jim Stichnothff9c7062014-09-18 04:50:49 -070032; CHECK: je
Jim Stichnothe5a5be72014-09-10 11:51:38 -070033; CHECK: mov [[PHI]], 0
Jim Stichnothe5a5be72014-09-10 11:51:38 -070034; CHECK: movzx {{.*}}, [[PHI]]
35
36define internal i32 @testPhi2(i32 %arg) {
37entry:
38 %cmp1 = icmp sgt i32 %arg, 0
39 br i1 %cmp1, label %next, label %target
40next:
41 br label %target
42target:
43 %merge = phi i32 [ 12345, %entry ], [ 54321, %next ]
44 ret i32 %merge
45}
46; Test that compare/branch fusing and Phi lowering happens as expected.
47; CHECK-LABEL: testPhi2
48; CHECK: mov {{.*}}, 12345
49; CHECK: cmp {{.*}}, 0
Jim Stichnothff9c7062014-09-18 04:50:49 -070050; CHECK-NEXT: jle
Jim Stichnothe5a5be72014-09-10 11:51:38 -070051; CHECK: mov [[PHI:.*]], 54321
Jim Stichnothe5a5be72014-09-10 11:51:38 -070052; CHECK: mov {{.*}}, [[PHI]]
53
54; ERRORS-NOT: ICE translation error
55; DUMP-NOT: SZ
Jim Stichnothe5ac7db2014-09-15 10:42:14 -070056
57; Test that address mode inference doesn't extend past
58; multi-definition, non-SSA Phi temporaries.
59define internal i32 @testPhi3(i32 %arg) {
60entry:
61 br label %body
62body:
63 %merge = phi i32 [ %arg, %entry ], [ %elt, %body ]
64 %interior = add i32 %merge, 1000
65 %__4 = inttoptr i32 %interior to i32*
66 %elt = load i32* %__4, align 1
67 %cmp = icmp eq i32 %elt, 0
68 br i1 %cmp, label %exit, label %body
69exit:
70 %__6 = inttoptr i32 %interior to i32*
71 store i32 %arg, i32* %__6, align 1
72 ret i32 %arg
73}
74; I can't figure out how to reliably test this for correctness, so I
75; will just include patterns for the entire current O2 sequence. This
76; may need to be changed when meaningful optimizations are added.
77; The key is to avoid the "bad" pattern like this:
78;
79; testPhi3:
80; .LtestPhi3$entry:
81; mov eax, dword ptr [esp+4]
82; mov ecx, eax
83; .LtestPhi3$body:
84; mov ecx, dword ptr [ecx+1000]
85; cmp ecx, 0
86; jne .LtestPhi3$body
87; .LtestPhi3$exit:
88; mov dword ptr [ecx+1000], eax
89; ret
90;
91; This is bad because the final store address is supposed to be the
92; same as the load address in the loop, but it has clearly been
93; over-optimized into a null pointer dereference.
94
95; CHECK-LABEL: testPhi3
96; CHECK: push [[EBX:.*]]
97; CHECK: mov {{.*}}, dword ptr [esp
Jim Stichnothe5ac7db2014-09-15 10:42:14 -070098; CHECK: mov
99; CHECK: mov {{.*}}[[ADDR:.*1000]]
100; CHECK: cmp {{.*}}, 0
Jim Stichnothff9c7062014-09-18 04:50:49 -0700101; CHECK: jne
Jim Stichnothe5ac7db2014-09-15 10:42:14 -0700102; CHECK: mov {{.*}}[[ADDR]]
103; CHECK: pop [[EBX]]