• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
3
4; cmp with single-use load, should not form branch.
5define i32 @test1(double %a, double* nocapture %b, i32 %x, i32 %y)  {
6; CHECK-LABEL: test1:
7; CHECK:       # BB#0:
8; CHECK-NEXT:    ucomisd (%rdi), %xmm0
9; CHECK-NEXT:    cmovbel %edx, %esi
10; CHECK-NEXT:    movl %esi, %eax
11; CHECK-NEXT:    retq
12;
13  %load = load double, double* %b, align 8
14  %cmp = fcmp olt double %load, %a
15  %cond = select i1 %cmp, i32 %x, i32 %y
16  ret i32 %cond
17}
18
19; Sanity check: no load.
20define i32 @test2(double %a, double %b, i32 %x, i32 %y)  {
21; CHECK-LABEL: test2:
22; CHECK:       # BB#0:
23; CHECK-NEXT:    ucomisd %xmm1, %xmm0
24; CHECK-NEXT:    cmovbel %esi, %edi
25; CHECK-NEXT:    movl %edi, %eax
26; CHECK-NEXT:    retq
27;
28  %cmp = fcmp ogt double %a, %b
29  %cond = select i1 %cmp, i32 %x, i32 %y
30  ret i32 %cond
31}
32
33; Multiple uses of the load.
34define i32 @test4(i32 %a, i32* nocapture %b, i32 %x, i32 %y)  {
35; CHECK-LABEL: test4:
36; CHECK:       # BB#0:
37; CHECK-NEXT:    movl (%rsi), %eax
38; CHECK-NEXT:    cmpl %edi, %eax
39; CHECK-NEXT:    cmovael %ecx, %edx
40; CHECK-NEXT:    addl %edx, %eax
41; CHECK-NEXT:    retq
42;
43  %load = load i32, i32* %b, align 4
44  %cmp = icmp ult i32 %load, %a
45  %cond = select i1 %cmp, i32 %x, i32 %y
46  %add = add i32 %cond, %load
47  ret i32 %add
48}
49
50; Multiple uses of the cmp.
51define i32 @test5(i32 %a, i32* nocapture %b, i32 %x, i32 %y) {
52; CHECK-LABEL: test5:
53; CHECK:       # BB#0:
54; CHECK-NEXT:    cmpl %edi, (%rsi)
55; CHECK-NEXT:    cmoval %edi, %ecx
56; CHECK-NEXT:    cmovael %edx, %ecx
57; CHECK-NEXT:    movl %ecx, %eax
58; CHECK-NEXT:    retq
59;
60  %load = load i32, i32* %b, align 4
61  %cmp = icmp ult i32 %load, %a
62  %cmp1 = icmp ugt i32 %load, %a
63  %cond = select i1 %cmp1, i32 %a, i32 %y
64  %cond5 = select i1 %cmp, i32 %cond, i32 %x
65  ret i32 %cond5
66}
67
68; If a select is not obviously predictable, don't turn it into a branch.
69define i32 @weighted_select1(i32 %a, i32 %b) {
70; CHECK-LABEL: weighted_select1:
71; CHECK:       # BB#0:
72; CHECK-NEXT:    testl %edi, %edi
73; CHECK-NEXT:    cmovnel %edi, %esi
74; CHECK-NEXT:    movl %esi, %eax
75; CHECK-NEXT:    retq
76;
77  %cmp = icmp ne i32 %a, 0
78  %sel = select i1 %cmp, i32 %a, i32 %b, !prof !0
79  ret i32 %sel
80}
81
82; If a select is obviously predictable, turn it into a branch.
83define i32 @weighted_select2(i32 %a, i32 %b) {
84; CHECK-LABEL: weighted_select2:
85; CHECK:       # BB#0:
86; CHECK-NEXT:    testl %edi, %edi
87; CHECK-NEXT:    jne [[LABEL_BB5:.*]]
88; CHECK:         movl %esi, %edi
89; CHECK-NEXT:  [[LABEL_BB5]]
90; CHECK-NEXT:    movl %edi, %eax
91; CHECK-NEXT:    retq
92;
93  %cmp = icmp ne i32 %a, 0
94  %sel = select i1 %cmp, i32 %a, i32 %b, !prof !1
95  ret i32 %sel
96}
97
98; Note the reversed profile weights: it doesn't matter if it's
99; obviously true or obviously false.
100; Either one should become a branch rather than conditional move.
101; TODO: But likely true vs. likely false should affect basic block placement?
102define i32 @weighted_select3(i32 %a, i32 %b) {
103; CHECK-LABEL: weighted_select3:
104; CHECK:       # BB#0:
105; CHECK-NEXT:    testl %edi, %edi
106; CHECK-NEXT:    jne [[LABEL_BB6:.*]]
107; CHECK:         movl %esi, %edi
108; CHECK-NEXT:  [[LABEL_BB6]]
109; CHECK-NEXT:    movl %edi, %eax
110; CHECK-NEXT:    retq
111;
112  %cmp = icmp ne i32 %a, 0
113  %sel = select i1 %cmp, i32 %a, i32 %b, !prof !2
114  ret i32 %sel
115}
116
117; Weightlessness is no reason to die.
118define i32 @unweighted_select(i32 %a, i32 %b) {
119; CHECK-LABEL: unweighted_select:
120; CHECK:       # BB#0:
121; CHECK-NEXT:    testl %edi, %edi
122; CHECK-NEXT:    cmovnel %edi, %esi
123; CHECK-NEXT:    movl %esi, %eax
124; CHECK-NEXT:    retq
125;
126  %cmp = icmp ne i32 %a, 0
127  %sel = select i1 %cmp, i32 %a, i32 %b, !prof !3
128  ret i32 %sel
129}
130
131!0 = !{!"branch_weights", i32 1, i32 99}
132!1 = !{!"branch_weights", i32 1, i32 100}
133!2 = !{!"branch_weights", i32 100, i32 1}
134!3 = !{!"branch_weights", i32 0, i32 0}
135
136