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 24define 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 37entry: 38 %mul = fmul double %x, %y 39 %cmp = fcmp une double %mul, 0.000000e+00 40 br i1 %cmp, label %bb2, label %bb1 41 42bb1: 43 %add = fadd double %mul, -1.000000e+00 44 br label %bb2 45 46bb2: 47 %phi = phi double [ %add, %bb1 ], [ %mul, %entry ] 48 ret double %phi 49} 50 51define 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 65entry: 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 70bb1: 71 %add = fadd double %mul, -1.000000e+00 72 br label %bb2 73 74bb2: 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 82define 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 93entry: 94 %cmp = fcmp une float %f, 0.000000e+00 95 br i1 %cmp, label %if.then, label %if.end 96 97if.then: 98 tail call void @a() 99 br label %if.end 100 101if.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]] 112define void @pr27750(i32* %b, float %x, i1 %y) { 113entry: 114 br label %for.cond 115 116for.cond: 117 br label %for.cond1 118 119for.cond1: 120 br i1 %y, label %for.body3.lr.ph, label %for.end 121 122for.body3.lr.ph: 123 store i32 0, i32* %b, align 4 124 br label %for.end 125 126for.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 133declare void @a() 134 135!1 = !{!"branch_weights", i32 1, i32 1000} 136