diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-01-20 22:18:47 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-01-20 22:18:47 +0000 |
| commit | 0c1c70aef4a1d97188fde20e894bafeccd64224c (patch) | |
| tree | 93df8c022e8f943244b21ba8e5bf5784b2f5da7a /llvm/test/Transforms | |
| parent | 867be0d14ce393108d848bcd9d080a92ca6b0006 (diff) | |
| download | bcm5719-llvm-0c1c70aef4a1d97188fde20e894bafeccd64224c.tar.gz bcm5719-llvm-0c1c70aef4a1d97188fde20e894bafeccd64224c.zip | |
[ValueTracking] recognize variations of 'clamp' to improve codegen (PR31693)
By enhancing value tracking, we allow an existing min/max canonicalization to
kick in and improve codegen for several targets that have min/max instructions.
Unfortunately, recognizing min/max in value tracking may cause us to hit
a hack in InstCombiner::visitICmpInst() more often:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/109340.html
...but I'm hoping we can remove that soon.
Correctness proofs based on Alive:
Name: smaxmin
Pre: C1 < C2
%cmp2 = icmp slt i8 %x, C2
%min = select i1 %cmp2, i8 %x, i8 C2
%cmp3 = icmp slt i8 %x, C1
%r = select i1 %cmp3, i8 C1, i8 %min
=>
%cmp2 = icmp slt i8 %x, C2
%min = select i1 %cmp2, i8 %x, i8 C2
%cmp1 = icmp sgt i8 %min, C1
%r = select i1 %cmp1, i8 %min, i8 C1
Name: sminmax
Pre: C1 > C2
%cmp2 = icmp sgt i8 %x, C2
%max = select i1 %cmp2, i8 %x, i8 C2
%cmp3 = icmp sgt i8 %x, C1
%r = select i1 %cmp3, i8 C1, i8 %max
=>
%cmp2 = icmp sgt i8 %x, C2
%max = select i1 %cmp2, i8 %x, i8 C2
%cmp1 = icmp slt i8 %max, C1
%r = select i1 %cmp1, i8 %max, i8 C1
----------------------------------------
Optimization: smaxmin
Done: 1
Optimization is correct!
----------------------------------------
Optimization: sminmax
Done: 1
Optimization is correct!
Name: umaxmin
Pre: C1 u< C2
%cmp2 = icmp ult i8 %x, C2
%min = select i1 %cmp2, i8 %x, i8 C2
%cmp3 = icmp ult i8 %x, C1
%r = select i1 %cmp3, i8 C1, i8 %min
=>
%cmp2 = icmp ult i8 %x, C2
%min = select i1 %cmp2, i8 %x, i8 C2
%cmp1 = icmp ugt i8 %min, C1
%r = select i1 %cmp1, i8 %min, i8 C1
Name: uminmax
Pre: C1 u> C2
%cmp2 = icmp ugt i8 %x, C2
%max = select i1 %cmp2, i8 %x, i8 C2
%cmp3 = icmp ugt i8 %x, C1
%r = select i1 %cmp3, i8 C1, i8 %max
=>
%cmp2 = icmp ugt i8 %x, C2
%max = select i1 %cmp2, i8 %x, i8 C2
%cmp1 = icmp ult i8 %max, C1
%r = select i1 %cmp1, i8 %max, i8 C1
----------------------------------------
Optimization: umaxmin
Done: 1
Optimization is correct!
----------------------------------------
Optimization: uminmax
Done: 1
Optimization is correct!
llvm-svn: 292660
Diffstat (limited to 'llvm/test/Transforms')
| -rw-r--r-- | llvm/test/Transforms/InstCombine/minmax-fold.ll | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll index ec838e25f31..adb99c283c2 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fold.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll @@ -348,8 +348,8 @@ define i32 @clamp_signed1(i32 %x) { ; CHECK-LABEL: @clamp_signed1( ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 %x, 255 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 %x, i32 255 -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %x, 15 -; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 15, i32 [[MIN]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[MIN]], 15 +; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15 ; CHECK-NEXT: ret i32 [[R]] ; %cmp2 = icmp slt i32 %x, 255 @@ -365,8 +365,8 @@ define i32 @clamp_signed2(i32 %x) { ; CHECK-LABEL: @clamp_signed2( ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, 15 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 %x, i32 15 -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 %x, 255 -; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 255, i32 [[MAX]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[MAX]], 255 +; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255 ; CHECK-NEXT: ret i32 [[R]] ; %cmp2 = icmp sgt i32 %x, 15 @@ -382,8 +382,8 @@ define i32 @clamp_unsigned1(i32 %x) { ; CHECK-LABEL: @clamp_unsigned1( ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, 255 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 %x, i32 255 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, 15 -; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 15, i32 [[MIN]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[MIN]], 15 +; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[MIN]], i32 15 ; CHECK-NEXT: ret i32 [[R]] ; %cmp2 = icmp ult i32 %x, 255 @@ -399,8 +399,8 @@ define i32 @clamp_unsigned2(i32 %x) { ; CHECK-LABEL: @clamp_unsigned2( ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, 15 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 %x, i32 15 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, 255 -; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 255, i32 [[MAX]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[MAX]], 255 +; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i32 [[MAX]], i32 255 ; CHECK-NEXT: ret i32 [[R]] ; %cmp2 = icmp ugt i32 %x, 15 |

