Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DAGCombiner: Canonicalize select(and/or,x,y) depending on target.
This is based on the following equivalences: select(C0 & C1, X, Y) <=> select(C0, select(C1, X, Y), Y) select(C0 | C1, X, Y) <=> select(C0, X, select(C1, X, Y)) Many target cannot perform and/or on the CPU flags and therefore the right side should be choosen to avoid materializign the i1 flags in an integer register. If the target can perform this operation efficiently we normalize to the left form. Differential Revision: http://reviews.llvm.org/D7622 llvm-svn: 231507
- Loading branch information
Showing
7 changed files
with
197 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
; RUN: llc -o - %s | FileCheck %s | ||
target triple = "arm-unknown-unknown" | ||
|
||
; select with and i1/or i1 condition should be implemented as a series of 2 | ||
; cmovs, not by producing two conditions and using and on them. | ||
|
||
define i32 @select_and(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5) { | ||
; CHECK-LABEL: select_and | ||
; CHECK-NOT: tst | ||
; CHECK-NOT: movne | ||
; CHECK: mov{{lo|hs}} | ||
; CHECK: mov{{lo|hs}} | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = icmp ult i32 %a2, %a3 | ||
%and = and i1 %cmp0, %cmp1 | ||
%res = select i1 %and, i32 %a4, i32 %a5 | ||
ret i32 %res | ||
} | ||
|
||
define i32 @select_or(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5) { | ||
; select with and i1 condition should be implemented as a series of 2 cmovs, not | ||
; by producing two conditions and using and on them. | ||
; CHECK-LABEL: select_or | ||
; CHECK-NOT: orss | ||
; CHECK-NOT: tst | ||
; CHECK: mov{{lo|hs}} | ||
; CHECK: mov{{lo|hs}} | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = icmp ult i32 %a2, %a3 | ||
%and = or i1 %cmp0, %cmp1 | ||
%res = select i1 %and, i32 %a4, i32 %a5 | ||
ret i32 %res | ||
} | ||
|
||
; If one of the conditions is materialized as a 0/1 value anyway, then the | ||
; sequence of 2 cmovs should not be used. | ||
|
||
@var32 = global i32 0 | ||
define i32 @select_noopt(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4) { | ||
; CHECK-LABEL: select_noopt | ||
; CHECK: orrs | ||
; CHECK: movne | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = icmp ult i32 %a1, %a2 | ||
%or = or i1 %cmp0, %cmp1 | ||
%zero_one = zext i1 %or to i32 | ||
store volatile i32 %zero_one, i32* @var32 | ||
%res = select i1 %or, i32 %a3, i32 %a4 | ||
ret i32 %res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
; RUN: llc -o - %s | FileCheck %s | ||
target triple = "x86_64-unknown-unknown" | ||
|
||
; select with and i1/or i1 condition should be implemented as a series of 2 | ||
; cmovs, not by producing two conditions and using and on them. | ||
|
||
define i32 @select_and(i32 %a0, i32 %a1, float %a2, float %a3, i32 %a4, i32 %a5) { | ||
; CHECK-LABEL: select_and | ||
; CHECK-NOT: set | ||
; CHECK-NOT: and[lb] | ||
; CHECK-NOT: test | ||
; CHECK: cmov | ||
; CHECK: cmov | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = fcmp olt float %a2, %a3 | ||
%and = and i1 %cmp0, %cmp1 | ||
%res = select i1 %and, i32 %a4, i32 %a5 | ||
ret i32 %res | ||
} | ||
|
||
define i32 @select_or(i32 %a0, i32 %a1, float %a2, float %a3, i32 %a4, i32 %a5) { | ||
; select with and i1 condition should be implemented as a series of 2 cmovs, not | ||
; by producing two conditions and using and on them. | ||
; CHECK-LABEL: select_or | ||
; CHECK-NOT: set | ||
; CHECK-NOT: or[lb] | ||
; CHECK-NOT: test | ||
; CHECK: cmov | ||
; CHECK: cmov | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = fcmp olt float %a2, %a3 | ||
%and = or i1 %cmp0, %cmp1 | ||
%res = select i1 %and, i32 %a4, i32 %a5 | ||
ret i32 %res | ||
} | ||
|
||
; If one of the conditions is materialized as a 0/1 value anyway, then the | ||
; sequence of 2 cmovs should not be used. | ||
|
||
@var32 = global i32 0 | ||
define i32 @select_noopt(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4) { | ||
; CHECK-LABEL: select_noopt | ||
; CHECK: cmov | ||
; CHECK-NOT: cmov | ||
%cmp0 = icmp ult i32 %a0, %a1 | ||
%cmp1 = icmp ult i32 %a1, %a2 | ||
%or = or i1 %cmp0, %cmp1 | ||
%zero_one = zext i1 %or to i32 | ||
store volatile i32 %zero_one, i32* @var32 | ||
%res = select i1 %or, i32 %a3, i32 %a4 | ||
ret i32 %res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters