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