forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EarlyCSE] add tests for commuted min/max; NFC
See PR35642: https://bugs.llvm.org/show_bug.cgi?id=35642 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320530 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
1 parent
6c7d448
commit 0dace14
Showing
1 changed file
with
173 additions
and
25 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,215 @@ | ||
; RUN: opt < %s -S -early-cse | FileCheck %s | ||
; RUN: opt < %s -S -basicaa -early-cse-memssa | FileCheck %s | ||
|
||
; CHECK-LABEL: @test1( | ||
define void @test1(float %A, float %B, float* %PA, float* %PB) { | ||
; CHECK-NEXT: fadd | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: ret | ||
; CHECK-LABEL: @test1( | ||
; CHECK-NEXT: [[C:%.*]] = fadd float %A, %B | ||
; CHECK-NEXT: store float [[C]], float* %PA | ||
; CHECK-NEXT: store float [[C]], float* %PB | ||
; CHECK-NEXT: ret void | ||
; | ||
%C = fadd float %A, %B | ||
store float %C, float* %PA | ||
%D = fadd float %B, %A | ||
store float %D, float* %PB | ||
ret void | ||
} | ||
|
||
; CHECK-LABEL: @test2( | ||
define void @test2(float %A, float %B, i1* %PA, i1* %PB) { | ||
; CHECK-NEXT: fcmp | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: ret | ||
; CHECK-LABEL: @test2( | ||
; CHECK-NEXT: [[C:%.*]] = fcmp oeq float %A, %B | ||
; CHECK-NEXT: store i1 [[C]], i1* %PA | ||
; CHECK-NEXT: store i1 [[C]], i1* %PB | ||
; CHECK-NEXT: ret void | ||
; | ||
%C = fcmp oeq float %A, %B | ||
store i1 %C, i1* %PA | ||
%D = fcmp oeq float %B, %A | ||
store i1 %D, i1* %PB | ||
ret void | ||
} | ||
|
||
; CHECK-LABEL: @test3( | ||
define void @test3(float %A, float %B, i1* %PA, i1* %PB) { | ||
; CHECK-NEXT: fcmp | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: ret | ||
; CHECK-LABEL: @test3( | ||
; CHECK-NEXT: [[C:%.*]] = fcmp uge float %A, %B | ||
; CHECK-NEXT: store i1 [[C]], i1* %PA | ||
; CHECK-NEXT: store i1 [[C]], i1* %PB | ||
; CHECK-NEXT: ret void | ||
; | ||
%C = fcmp uge float %A, %B | ||
store i1 %C, i1* %PA | ||
%D = fcmp ule float %B, %A | ||
store i1 %D, i1* %PB | ||
ret void | ||
} | ||
|
||
; CHECK-LABEL: @test4( | ||
define void @test4(i32 %A, i32 %B, i1* %PA, i1* %PB) { | ||
; CHECK-NEXT: icmp | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: ret | ||
; CHECK-LABEL: @test4( | ||
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 %A, %B | ||
; CHECK-NEXT: store i1 [[C]], i1* %PA | ||
; CHECK-NEXT: store i1 [[C]], i1* %PB | ||
; CHECK-NEXT: ret void | ||
; | ||
%C = icmp eq i32 %A, %B | ||
store i1 %C, i1* %PA | ||
%D = icmp eq i32 %B, %A | ||
store i1 %D, i1* %PB | ||
ret void | ||
} | ||
|
||
; CHECK-LABEL: @test5( | ||
define void @test5(i32 %A, i32 %B, i1* %PA, i1* %PB) { | ||
; CHECK-NEXT: icmp | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: store | ||
; CHECK-NEXT: ret | ||
; CHECK-LABEL: @test5( | ||
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 %A, %B | ||
; CHECK-NEXT: store i1 [[C]], i1* %PA | ||
; CHECK-NEXT: store i1 [[C]], i1* %PB | ||
; CHECK-NEXT: ret void | ||
; | ||
%C = icmp sgt i32 %A, %B | ||
store i1 %C, i1* %PA | ||
%D = icmp slt i32 %B, %A | ||
store i1 %D, i1* %PB | ||
ret void | ||
} | ||
|
||
; Min/max operands may be commuted in the compare and select. | ||
|
||
define i8 @smin_commute(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @smin_commute( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %b, %a | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[R:%.*]] = mul i8 [[M1]], [[M2]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp slt i8 %a, %b | ||
%cmp2 = icmp slt i8 %b, %a | ||
%m1 = select i1 %cmp1, i8 %a, i8 %b | ||
%m2 = select i1 %cmp2, i8 %b, i8 %a | ||
%r = mul i8 %m1, %m2 | ||
ret i8 %r | ||
} | ||
|
||
; Min/max can also have a swapped predicate and select operands. | ||
|
||
define i1 @smin_swapped(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @smin_swapped( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %a, %b | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M2]], [[M1]] | ||
; CHECK-NEXT: ret i1 [[R]] | ||
; | ||
%cmp1 = icmp sgt i8 %a, %b | ||
%cmp2 = icmp slt i8 %a, %b | ||
%m1 = select i1 %cmp1, i8 %b, i8 %a | ||
%m2 = select i1 %cmp2, i8 %a, i8 %b | ||
%r = icmp eq i8 %m2, %m1 | ||
ret i1 %r | ||
} | ||
|
||
define i8 @smax_commute(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @smax_commute( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %b, %a | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[R:%.*]] = urem i8 [[M2]], [[M1]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp sgt i8 %a, %b | ||
%cmp2 = icmp sgt i8 %b, %a | ||
%m1 = select i1 %cmp1, i8 %a, i8 %b | ||
%m2 = select i1 %cmp2, i8 %b, i8 %a | ||
%r = urem i8 %m2, %m1 | ||
ret i8 %r | ||
} | ||
|
||
define i8 @smax_swapped(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @smax_swapped( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %a, %b | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[M1]], [[M2]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp slt i8 %a, %b | ||
%cmp2 = icmp sgt i8 %a, %b | ||
%m1 = select i1 %cmp1, i8 %b, i8 %a | ||
%m2 = select i1 %cmp2, i8 %a, i8 %b | ||
%r = sdiv i8 %m1, %m2 | ||
ret i8 %r | ||
} | ||
|
||
define i8 @umin_commute(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @umin_commute( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 %b, %a | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[R:%.*]] = sub i8 [[M2]], [[M1]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp ult i8 %a, %b | ||
%cmp2 = icmp ult i8 %b, %a | ||
%m1 = select i1 %cmp1, i8 %a, i8 %b | ||
%m2 = select i1 %cmp2, i8 %b, i8 %a | ||
%r = sub i8 %m2, %m1 | ||
ret i8 %r | ||
} | ||
|
||
; Choose a vector type just to show that works. | ||
|
||
define <2 x i8> @umin_swapped(<2 x i8> %a, <2 x i8> %b) { | ||
; CHECK-LABEL: @umin_swapped( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i8> %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> %a, %b | ||
; CHECK-NEXT: [[M1:%.*]] = select <2 x i1> [[CMP1]], <2 x i8> %b, <2 x i8> %a | ||
; CHECK-NEXT: [[M2:%.*]] = select <2 x i1> [[CMP2]], <2 x i8> %a, <2 x i8> %b | ||
; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[M2]], [[M1]] | ||
; CHECK-NEXT: ret <2 x i8> [[R]] | ||
; | ||
%cmp1 = icmp ugt <2 x i8> %a, %b | ||
%cmp2 = icmp ult <2 x i8> %a, %b | ||
%m1 = select <2 x i1> %cmp1, <2 x i8> %b, <2 x i8> %a | ||
%m2 = select <2 x i1> %cmp2, <2 x i8> %a, <2 x i8> %b | ||
%r = sub <2 x i8> %m2, %m1 | ||
ret <2 x i8> %r | ||
} | ||
|
||
define i8 @umax_commute(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @umax_commute( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %b, %a | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[R:%.*]] = udiv i8 [[M1]], [[M2]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp ugt i8 %a, %b | ||
%cmp2 = icmp ugt i8 %b, %a | ||
%m1 = select i1 %cmp1, i8 %a, i8 %b | ||
%m2 = select i1 %cmp2, i8 %b, i8 %a | ||
%r = udiv i8 %m1, %m2 | ||
ret i8 %r | ||
} | ||
|
||
define i8 @umax_swapped(i8 %a, i8 %b) { | ||
; CHECK-LABEL: @umax_swapped( | ||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b | ||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %a, %b | ||
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a | ||
; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b | ||
; CHECK-NEXT: [[R:%.*]] = add i8 [[M2]], [[M1]] | ||
; CHECK-NEXT: ret i8 [[R]] | ||
; | ||
%cmp1 = icmp ult i8 %a, %b | ||
%cmp2 = icmp ugt i8 %a, %b | ||
%m1 = select i1 %cmp1, i8 %b, i8 %a | ||
%m2 = select i1 %cmp2, i8 %a, i8 %b | ||
%r = add i8 %m2, %m1 | ||
ret i8 %r | ||
} | ||
|