2016-03-08 06:53:23 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
|
|
|
|
|
2013-09-20 05:58:20 +08:00
|
|
|
; <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:
|
|
|
|
|
2016-03-08 06:53:23 +08:00
|
|
|
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 {{.*}}(%rip), %xmm0
|
|
|
|
; CHECK-NEXT: .LBB0_2: # %bb2
|
|
|
|
; CHECK-NEXT: retq
|
2013-09-20 05:58:20 +08:00
|
|
|
|
2016-01-27 04:08:01 +08:00
|
|
|
entry:
|
2016-03-08 06:53:23 +08:00
|
|
|
%mul = fmul double %x, %y
|
2017-02-01 07:48:32 +08:00
|
|
|
%cmp = fcmp oeq double %mul, 0.000000e+00
|
|
|
|
br i1 %cmp, label %bb1, label %bb2
|
2016-01-27 04:08:01 +08:00
|
|
|
|
|
|
|
bb1:
|
2016-03-08 06:53:23 +08:00
|
|
|
%add = fadd double %mul, -1.000000e+00
|
2016-01-27 04:08:01 +08:00
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb2:
|
2016-03-08 06:53:23 +08:00
|
|
|
%phi = phi double [ %add, %bb1 ], [ %mul, %entry ]
|
|
|
|
ret double %phi
|
2016-01-27 04:08:01 +08:00
|
|
|
}
|
2016-03-08 06:53:23 +08:00
|
|
|
|
2016-03-08 07:13:06 +08:00
|
|
|
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
|
2016-03-24 05:45:37 +08:00
|
|
|
; CHECK-NEXT: jp .LBB1_1
|
Codegen: Tail-duplicate during placement.
The tail duplication pass uses an assumed layout when making duplication
decisions. This is fine, but passes up duplication opportunities that
may arise when blocks are outlined. Because we want the updated CFG to
affect subsequent placement decisions, this change must occur during
placement.
In order to achieve this goal, TailDuplicationPass is split into a
utility class, TailDuplicator, and the pass itself. The pass delegates
nearly everything to the TailDuplicator object, except for looping over
the blocks in a function. This allows the same code to be used for tail
duplication in both places.
This change, in concert with outlining optional branches, allows
triangle shaped code to perform much better, esepecially when the
taken/untaken branches are correlated, as it creates a second spine when
the tests are small enough.
Issue from previous rollback fixed, and a new test was added for that
case as well. Issue was worklist/scheduling/taildup issue in layout.
Issue from 2nd rollback fixed, with 2 additional tests. Issue was
tail merging/loop info/tail-duplication causing issue with loops that share
a header block.
Issue with early tail-duplication of blocks that branch to a fallthrough
predecessor fixed with test case: tail-dup-branch-to-fallthrough.ll
Differential revision: https://reviews.llvm.org/D18226
llvm-svn: 283934
2016-10-12 04:36:43 +08:00
|
|
|
; CHECK-NEXT: # %bb2
|
2016-03-08 07:13:06 +08:00
|
|
|
; CHECK-NEXT: retq
|
2016-03-24 05:45:37 +08:00
|
|
|
; CHECK-NEXT: .LBB1_1: # %bb1
|
|
|
|
; CHECK-NEXT: addsd {{.*}}(%rip), %xmm0
|
Codegen: Tail-duplicate during placement.
The tail duplication pass uses an assumed layout when making duplication
decisions. This is fine, but passes up duplication opportunities that
may arise when blocks are outlined. Because we want the updated CFG to
affect subsequent placement decisions, this change must occur during
placement.
In order to achieve this goal, TailDuplicationPass is split into a
utility class, TailDuplicator, and the pass itself. The pass delegates
nearly everything to the TailDuplicator object, except for looping over
the blocks in a function. This allows the same code to be used for tail
duplication in both places.
This change, in concert with outlining optional branches, allows
triangle shaped code to perform much better, esepecially when the
taken/untaken branches are correlated, as it creates a second spine when
the tests are small enough.
Issue from previous rollback fixed, and a new test was added for that
case as well. Issue was worklist/scheduling/taildup issue in layout.
Issue from 2nd rollback fixed, with 2 additional tests. Issue was
tail merging/loop info/tail-duplication causing issue with loops that share
a header block.
Issue with early tail-duplication of blocks that branch to a fallthrough
predecessor fixed with test case: tail-dup-branch-to-fallthrough.ll
Differential revision: https://reviews.llvm.org/D18226
llvm-svn: 283934
2016-10-12 04:36:43 +08:00
|
|
|
; CHECK-NEXT: retq
|
2016-03-08 07:13:06 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-03-24 05:45:37 +08:00
|
|
|
; Test if the negation of the non-equality check between floating points are
|
|
|
|
; translated to jnp followed by jne.
|
2016-03-08 07:13:06 +08:00
|
|
|
|
2016-03-24 05:45:37 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-05-17 20:47:46 +08:00
|
|
|
; Test that an FP oeq/une conditional branch can be inverted successfully even
|
|
|
|
; when the true and false targets are the same (PR27750).
|
|
|
|
;
|
|
|
|
; CHECK-LABEL: pr27750
|
|
|
|
; CHECK: ucomiss
|
|
|
|
; CHECK-NEXT: jne [[TARGET:.*]]
|
|
|
|
; CHECK-NEXT: jp [[TARGET]]
|
|
|
|
define void @pr27750(i32* %b, float %x, i1 %y) {
|
|
|
|
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, i32* %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
|
|
|
|
}
|
|
|
|
|
2016-03-24 05:45:37 +08:00
|
|
|
declare void @a()
|
|
|
|
|
|
|
|
!1 = !{!"branch_weights", i32 1, i32 1000}
|