1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3 4 ; <rdar://problem/7859988> 5 6 ; Make sure we don't generate more jumps than we need to. We used to generate 7 ; something like this: 8 ; 9 ; jne LBB0_1 10 ; jnp LBB0_2 11 ; LBB0_1: 12 ; jmp LBB0_3 13 ; LBB0_2: 14 ; addsd ... 15 ; LBB0_3: 16 ; 17 ; Now we generate this: 18 ; 19 ; jne LBB0_2 20 ; jp LBB0_2 21 ; addsd ... 22 ; LBB0_2: 23 24 define double @rdar_7859988(double %x, double %y) nounwind readnone optsize ssp { 25 ; CHECK-LABEL: rdar_7859988: 26 ; CHECK: # BB#0: # %entry 27 ; CHECK-NEXT: mulsd %xmm1, %xmm0 28 ; CHECK-NEXT: xorpd %xmm1, %xmm1 29 ; CHECK-NEXT: ucomisd %xmm1, %xmm0 30 ; CHECK-NEXT: jne .LBB0_2 31 ; CHECK-NEXT: jp .LBB0_2 32 ; CHECK-NEXT: # BB#1: # %bb1 33 ; CHECK-NEXT: addsd {{.*}}(%rip), %xmm0 34 ; CHECK-NEXT: .LBB0_2: # %bb2 35 ; CHECK-NEXT: retq 36 37 entry: 38 %mul = fmul double %x, %y 39 %cmp = fcmp une double %mul, 0.000000e+00 40 br i1 %cmp, label %bb2, label %bb1 41 42 bb1: 43 %add = fadd double %mul, -1.000000e+00 44 br label %bb2 45 46 bb2: 47 %phi = phi double [ %add, %bb1 ], [ %mul, %entry ] 48 ret double %phi 49 } 50 51 define double @profile_metadata(double %x, double %y) { 52 ; CHECK-LABEL: profile_metadata: 53 ; CHECK: # BB#0: # %entry 54 ; CHECK-NEXT: mulsd %xmm1, %xmm0 55 ; CHECK-NEXT: xorpd %xmm1, %xmm1 56 ; CHECK-NEXT: ucomisd %xmm1, %xmm0 57 ; CHECK-NEXT: jne .LBB1_1 58 ; CHECK-NEXT: jp .LBB1_1 59 ; CHECK-NEXT: .LBB1_2: # %bb2 60 ; CHECK-NEXT: retq 61 ; CHECK-NEXT: .LBB1_1: # %bb1 62 ; CHECK-NEXT: addsd {{.*}}(%rip), %xmm0 63 ; CHECK-NEXT: jmp .LBB1_2 64 65 entry: 66 %mul = fmul double %x, %y 67 %cmp = fcmp une double %mul, 0.000000e+00 68 br i1 %cmp, label %bb1, label %bb2, !prof !1 69 70 bb1: 71 %add = fadd double %mul, -1.000000e+00 72 br label %bb2 73 74 bb2: 75 %phi = phi double [ %add, %bb1 ], [ %mul, %entry ] 76 ret double %phi 77 } 78 79 ; Test if the negation of the non-equality check between floating points are 80 ; translated to jnp followed by jne. 81 82 define void @foo(float %f) { 83 ; CHECK-LABEL: foo: 84 ; CHECK: # BB#0: # %entry 85 ; CHECK-NEXT: xorps %xmm1, %xmm1 86 ; CHECK-NEXT: ucomiss %xmm1, %xmm0 87 ; CHECK-NEXT: jne .LBB2_2 88 ; CHECK-NEXT: jnp .LBB2_1 89 ; CHECK-NEXT: .LBB2_2: # %if.then 90 ; CHECK-NEXT: jmp a # TAILCALL 91 ; CHECK-NEXT: .LBB2_1: # %if.end 92 ; CHECK-NEXT: retq 93 entry: 94 %cmp = fcmp une float %f, 0.000000e+00 95 br i1 %cmp, label %if.then, label %if.end 96 97 if.then: 98 tail call void @a() 99 br label %if.end 100 101 if.end: 102 ret void 103 } 104 105 ; Test that an FP oeq/une conditional branch can be inverted successfully even 106 ; when the true and false targets are the same (PR27750). 107 ; 108 ; CHECK-LABEL: pr27750 109 ; CHECK: ucomiss 110 ; CHECK-NEXT: jne [[TARGET:.*]] 111 ; CHECK-NEXT: jp [[TARGET]] 112 define void @pr27750(i32* %b, float %x, i1 %y) { 113 entry: 114 br label %for.cond 115 116 for.cond: 117 br label %for.cond1 118 119 for.cond1: 120 br i1 %y, label %for.body3.lr.ph, label %for.end 121 122 for.body3.lr.ph: 123 store i32 0, i32* %b, align 4 124 br label %for.end 125 126 for.end: 127 ; After block %for.cond gets eliminated, the two target blocks of this 128 ; conditional block are the same. 129 %tobool = fcmp une float %x, 0.000000e+00 130 br i1 %tobool, label %for.cond, label %for.cond1 131 } 132 133 declare void @a() 134 135 !1 = !{!"branch_weights", i32 1, i32 1000} 136