2017-11-15 05:44:09 +08:00
|
|
|
; RUN: llc -mtriple=x86_64-- -asm-verbose=false < %s -jump-table-density=40 -switch-peel-threshold=101 | FileCheck %s
|
2010-06-24 10:06:24 +08:00
|
|
|
|
|
|
|
; This switch should use bit tests, and the third bit test case is just
|
|
|
|
; testing for one possible value, so it doesn't need a bt.
|
|
|
|
|
|
|
|
; CHECK: movabsq $2305843009482129440, %r
|
|
|
|
; CHECK-NEXT: btq %rax, %r
|
Distribute the weight on the edge from switch to default statement to edges generated in lowering switch.
Currently, when edge weights are assigned to edges that are created when lowering switch statement, the weight on the edge to default statement (let's call it "default weight" here) is not considered. We need to distribute this weight properly. However, without value profiling, we have no idea how to distribute it. In this patch, I applied the heuristic that this weight is evenly distributed to successors.
For example, given a switch statement with cases 1,2,3,5,10,11,20, and every edge from switch to each successor has weight 10. If there is a binary search tree built to test if n < 10, then its two out-edges will have weight 4x10+10/2 = 45 and 3x10 + 10/2 = 35 respectively (currently they are 40 and 30 without considering the default weight). Each distribution (which is 5 here) will be stored in each SwitchWorkListItem for further distribution.
There are some exceptions:
For a jump table header which doesn't have any edge to default statement, we don't distribute the default weight to it.
For a bit test header which covers a contiguous range and hence has no edges to default statement, we don't distribute the default weight to it.
When the branch checks a single value or a contiguous range with no edge to default statement, we don't distribute the default weight to it.
In other cases, the default weight is evenly distributed to successors.
Differential Revision: http://reviews.llvm.org/D12418
llvm-svn: 246522
2015-09-01 09:42:16 +08:00
|
|
|
; CHECK-NEXT: jb
|
2012-04-16 21:49:17 +08:00
|
|
|
; CHECK: movl $671088640, %e
|
2010-06-24 10:06:24 +08:00
|
|
|
; CHECK-NEXT: btq %rax, %r
|
2012-04-16 21:49:17 +08:00
|
|
|
; CHECK-NEXT: jae
|
|
|
|
; CHECK: testq %rax, %r
|
2010-06-24 10:06:24 +08:00
|
|
|
; CHECK-NEXT: j
|
|
|
|
|
|
|
|
define void @test(i8* %l) nounwind {
|
|
|
|
entry:
|
|
|
|
%l.addr = alloca i8*, align 8 ; <i8**> [#uses=2]
|
|
|
|
store i8* %l, i8** %l.addr
|
2015-02-28 05:17:42 +08:00
|
|
|
%tmp = load i8*, i8** %l.addr ; <i8*> [#uses=1]
|
|
|
|
%tmp1 = load i8, i8* %tmp ; <i8> [#uses=1]
|
2010-06-24 10:06:24 +08:00
|
|
|
%conv = sext i8 %tmp1 to i32 ; <i32> [#uses=1]
|
|
|
|
switch i32 %conv, label %sw.default [
|
|
|
|
i32 62, label %sw.bb
|
|
|
|
i32 60, label %sw.bb
|
|
|
|
i32 38, label %sw.bb2
|
|
|
|
i32 94, label %sw.bb2
|
|
|
|
i32 61, label %sw.bb2
|
|
|
|
i32 33, label %sw.bb4
|
|
|
|
]
|
|
|
|
|
|
|
|
sw.bb: ; preds = %entry, %entry
|
|
|
|
call void @foo(i32 0)
|
|
|
|
br label %sw.epilog
|
|
|
|
|
|
|
|
sw.bb2: ; preds = %entry, %entry, %entry
|
|
|
|
call void @foo(i32 1)
|
|
|
|
br label %sw.epilog
|
|
|
|
|
|
|
|
sw.bb4: ; preds = %entry
|
|
|
|
call void @foo(i32 3)
|
|
|
|
br label %sw.epilog
|
|
|
|
|
|
|
|
sw.default: ; preds = %entry
|
|
|
|
call void @foo(i32 97)
|
|
|
|
br label %sw.epilog
|
|
|
|
|
|
|
|
sw.epilog: ; preds = %sw.default, %sw.bb4, %sw.bb2, %sw.bb
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @foo(i32)
|
2011-01-06 09:02:44 +08:00
|
|
|
|
|
|
|
; Don't zero extend the test operands to pointer type if it can be avoided.
|
|
|
|
; rdar://8781238
|
|
|
|
define void @test2(i32 %x) nounwind ssp {
|
2013-07-14 04:38:47 +08:00
|
|
|
; CHECK-LABEL: test2:
|
2011-01-06 09:02:44 +08:00
|
|
|
; CHECK: cmpl $6
|
|
|
|
; CHECK: ja
|
|
|
|
|
|
|
|
; CHECK-NEXT: movl $91
|
|
|
|
; CHECK-NOT: movl
|
|
|
|
; CHECK-NEXT: btl
|
2012-04-16 21:49:17 +08:00
|
|
|
; CHECK-NEXT: jae
|
2011-01-06 09:02:44 +08:00
|
|
|
entry:
|
|
|
|
switch i32 %x, label %if.end [
|
|
|
|
i32 6, label %if.then
|
|
|
|
i32 4, label %if.then
|
|
|
|
i32 3, label %if.then
|
|
|
|
i32 1, label %if.then
|
|
|
|
i32 0, label %if.then
|
|
|
|
]
|
|
|
|
|
|
|
|
if.then: ; preds = %entry, %entry, %entry, %entry, %entry
|
|
|
|
tail call void @bar() nounwind
|
|
|
|
ret void
|
|
|
|
|
|
|
|
if.end: ; preds = %entry
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @bar()
|
2011-07-14 09:38:42 +08:00
|
|
|
|
|
|
|
define void @test3(i32 %x) nounwind {
|
2013-07-14 04:38:47 +08:00
|
|
|
; CHECK-LABEL: test3:
|
2011-07-14 09:38:42 +08:00
|
|
|
; CHECK: cmpl $5
|
|
|
|
; CHECK: ja
|
|
|
|
; CHECK: cmpl $4
|
2012-04-16 21:49:17 +08:00
|
|
|
; CHECK: je
|
2011-07-14 09:38:42 +08:00
|
|
|
switch i32 %x, label %if.end [
|
|
|
|
i32 0, label %if.then
|
|
|
|
i32 1, label %if.then
|
|
|
|
i32 2, label %if.then
|
|
|
|
i32 3, label %if.then
|
|
|
|
i32 5, label %if.then
|
|
|
|
]
|
|
|
|
if.then:
|
|
|
|
tail call void @bar() nounwind
|
|
|
|
ret void
|
|
|
|
if.end:
|
|
|
|
ret void
|
|
|
|
}
|
2015-01-21 03:43:33 +08:00
|
|
|
|
|
|
|
; Ensure that optimizing for jump tables doesn't needlessly deteriorate the
|
|
|
|
; created binary tree search. See PR22262.
|
|
|
|
define void @test4(i32 %x, i32* %y) {
|
|
|
|
; CHECK-LABEL: test4:
|
|
|
|
|
|
|
|
entry:
|
|
|
|
switch i32 %x, label %sw.default [
|
|
|
|
i32 10, label %sw.bb
|
|
|
|
i32 20, label %sw.bb1
|
|
|
|
i32 30, label %sw.bb2
|
|
|
|
i32 40, label %sw.bb3
|
|
|
|
i32 50, label %sw.bb4
|
|
|
|
i32 60, label %sw.bb5
|
|
|
|
]
|
|
|
|
sw.bb:
|
|
|
|
store i32 1, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.bb1:
|
|
|
|
store i32 2, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.bb2:
|
|
|
|
store i32 3, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.bb3:
|
|
|
|
store i32 4, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.bb4:
|
|
|
|
store i32 5, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.bb5:
|
|
|
|
store i32 6, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.default:
|
|
|
|
store i32 7, i32* %y
|
|
|
|
br label %sw.epilog
|
|
|
|
sw.epilog:
|
|
|
|
ret void
|
|
|
|
|
|
|
|
; The balanced binary switch here would start with a comparison against 39, but
|
|
|
|
; it is currently starting with 29 because of the density-sum heuristic.
|
2015-04-24 00:45:24 +08:00
|
|
|
; CHECK: cmpl $39
|
2015-01-21 03:43:33 +08:00
|
|
|
; CHECK: jg
|
|
|
|
; CHECK: cmpl $10
|
2015-04-24 00:45:24 +08:00
|
|
|
; CHECK: je
|
2015-01-21 03:43:33 +08:00
|
|
|
; CHECK: cmpl $20
|
Distribute the weight on the edge from switch to default statement to edges generated in lowering switch.
Currently, when edge weights are assigned to edges that are created when lowering switch statement, the weight on the edge to default statement (let's call it "default weight" here) is not considered. We need to distribute this weight properly. However, without value profiling, we have no idea how to distribute it. In this patch, I applied the heuristic that this weight is evenly distributed to successors.
For example, given a switch statement with cases 1,2,3,5,10,11,20, and every edge from switch to each successor has weight 10. If there is a binary search tree built to test if n < 10, then its two out-edges will have weight 4x10+10/2 = 45 and 3x10 + 10/2 = 35 respectively (currently they are 40 and 30 without considering the default weight). Each distribution (which is 5 here) will be stored in each SwitchWorkListItem for further distribution.
There are some exceptions:
For a jump table header which doesn't have any edge to default statement, we don't distribute the default weight to it.
For a bit test header which covers a contiguous range and hence has no edges to default statement, we don't distribute the default weight to it.
When the branch checks a single value or a contiguous range with no edge to default statement, we don't distribute the default weight to it.
In other cases, the default weight is evenly distributed to successors.
Differential Revision: http://reviews.llvm.org/D12418
llvm-svn: 246522
2015-09-01 09:42:16 +08:00
|
|
|
; CHECK: je
|
|
|
|
; CHECK: cmpl $30
|
2015-01-21 03:43:33 +08:00
|
|
|
; CHECK: jne
|
2015-04-24 00:45:24 +08:00
|
|
|
; CHECK: cmpl $40
|
|
|
|
; CHECK: je
|
2015-01-21 03:43:33 +08:00
|
|
|
; CHECK: cmpl $50
|
Distribute the weight on the edge from switch to default statement to edges generated in lowering switch.
Currently, when edge weights are assigned to edges that are created when lowering switch statement, the weight on the edge to default statement (let's call it "default weight" here) is not considered. We need to distribute this weight properly. However, without value profiling, we have no idea how to distribute it. In this patch, I applied the heuristic that this weight is evenly distributed to successors.
For example, given a switch statement with cases 1,2,3,5,10,11,20, and every edge from switch to each successor has weight 10. If there is a binary search tree built to test if n < 10, then its two out-edges will have weight 4x10+10/2 = 45 and 3x10 + 10/2 = 35 respectively (currently they are 40 and 30 without considering the default weight). Each distribution (which is 5 here) will be stored in each SwitchWorkListItem for further distribution.
There are some exceptions:
For a jump table header which doesn't have any edge to default statement, we don't distribute the default weight to it.
For a bit test header which covers a contiguous range and hence has no edges to default statement, we don't distribute the default weight to it.
When the branch checks a single value or a contiguous range with no edge to default statement, we don't distribute the default weight to it.
In other cases, the default weight is evenly distributed to successors.
Differential Revision: http://reviews.llvm.org/D12418
llvm-svn: 246522
2015-09-01 09:42:16 +08:00
|
|
|
; CHECK: je
|
2015-01-21 03:43:33 +08:00
|
|
|
; CHECK: cmpl $60
|
|
|
|
; CHECK: jne
|
|
|
|
}
|
2019-09-30 16:47:46 +08:00
|
|
|
|
|
|
|
|
2019-10-02 22:35:06 +08:00
|
|
|
; Omit the range check when the default case is unreachable, see PR43129.
|
2019-09-30 16:47:46 +08:00
|
|
|
declare void @g(i32)
|
|
|
|
define void @test5(i32 %x) {
|
|
|
|
|
|
|
|
; CHECK-LABEL: test5
|
2019-10-02 22:35:06 +08:00
|
|
|
; CHECK-NOT: cmp
|
2019-09-30 16:47:46 +08:00
|
|
|
|
|
|
|
; 73 = 2^0 + 2^3 + 2^6
|
|
|
|
; CHECK: movl $73
|
|
|
|
; CHECK-NEXT: btl
|
|
|
|
; CHECK-NEXT: jb
|
|
|
|
|
|
|
|
; 146 = 2^1 + 2^4 + 2^7
|
|
|
|
; CHECK-NEXT: movl $146
|
|
|
|
; CHECK-NEXT: btl
|
|
|
|
; CHECK-NEXT: jae
|
|
|
|
|
|
|
|
|
|
|
|
entry:
|
|
|
|
switch i32 %x, label %return [
|
|
|
|
i32 0, label %bb0
|
|
|
|
i32 3, label %bb0
|
|
|
|
i32 6, label %bb0
|
|
|
|
|
|
|
|
i32 1, label %bb1
|
|
|
|
i32 4, label %bb1
|
|
|
|
i32 7, label %bb1
|
|
|
|
|
|
|
|
i32 2, label %bb2
|
|
|
|
i32 5, label %bb2
|
|
|
|
i32 8, label %bb2
|
|
|
|
]
|
|
|
|
bb0: tail call void @g(i32 0) br label %return
|
|
|
|
bb1: tail call void @g(i32 1) br label %return
|
|
|
|
bb2: tail call void @g(i32 2) br label %return
|
|
|
|
return: unreachable
|
|
|
|
}
|