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