[InstCombine] add icmp-xor tests to show vector neglect; NFC

Also, rename the tests and the file, add comments, and add more tests
because there are no existing tests for some of these folds.

These patterns are particularly important for crippled vector ISAs that
have limited compare predicates (PR33138).

llvm-svn: 303652
This commit is contained in:
Sanjay Patel 2017-05-23 16:53:05 +00:00
parent 4bbce51539
commit 7ad3dbe836
2 changed files with 197 additions and 87 deletions

View File

@ -1,87 +0,0 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
define i1 @test1(i8 %x, i8 %y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP:%.*]] = icmp ult i8 %x, %y
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 128
%Y = xor i8 %y, 128
%tmp = icmp slt i8 %X, %Y
ret i1 %tmp
}
define i1 @test2(i8 %x, i8 %y) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[TMP:%.*]] = icmp slt i8 %x, %y
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 128
%Y = xor i8 %y, 128
%tmp = icmp ult i8 %X, %Y
ret i1 %tmp
}
define i1 @test3(i8 %x) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i8 %x, -114
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 128
%tmp = icmp uge i8 %X, 15
ret i1 %tmp
}
define <2 x i1> @test3vec(<2 x i8> %x) {
; CHECK-LABEL: @test3vec(
; CHECK-NEXT: [[TMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -114, i8 -114>
; CHECK-NEXT: ret <2 x i1> [[TMP]]
;
%X = xor <2 x i8> %x, <i8 128, i8 128>
%tmp = icmp uge <2 x i8> %X, <i8 15, i8 15>
ret <2 x i1> %tmp
}
define i1 @test4(i8 %x, i8 %y) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[TMP:%.*]] = icmp ugt i8 %x, %y
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 127
%Y = xor i8 %y, 127
%tmp = icmp slt i8 %X, %Y
ret i1 %tmp
}
define i1 @test5(i8 %x, i8 %y) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i8 %x, %y
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 127
%Y = xor i8 %y, 127
%tmp = icmp ult i8 %X, %Y
ret i1 %tmp
}
define i1 @test6(i8 %x) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[TMP:%.*]] = icmp slt i8 %x, 113
; CHECK-NEXT: ret i1 [[TMP]]
;
%X = xor i8 %x, 127
%tmp = icmp uge i8 %X, 15
ret i1 %tmp
}
define <2 x i1> @test6vec(<2 x i8> %x) {
; CHECK-LABEL: @test6vec(
; CHECK-NEXT: [[TMP:%.*]] = icmp slt <2 x i8> %x, <i8 113, i8 113>
; CHECK-NEXT: ret <2 x i1> [[TMP]]
;
%X = xor <2 x i8> %x, <i8 127, i8 127>
%tmp = icmp uge <2 x i8> %X, <i8 15, i8 15>
ret <2 x i1> %tmp
}

View File

@ -0,0 +1,197 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
; icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b
define i1 @slt_to_ult(i8 %x, i8 %y) {
; CHECK-LABEL: @slt_to_ult(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 %x, %y
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 128
%b = xor i8 %y, 128
%cmp = icmp slt i8 %a, %b
ret i1 %cmp
}
; PR33138 - https://bugs.llvm.org/show_bug.cgi?id=33138
define <2 x i1> @slt_to_ult_splat(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @slt_to_ult_splat(
; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128>
; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128>
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 128, i8 128>
%b = xor <2 x i8> %y, <i8 128, i8 128>
%cmp = icmp slt <2 x i8> %a, %b
ret <2 x i1> %cmp
}
; Make sure that unsigned -> signed works too.
define i1 @ult_to_slt(i8 %x, i8 %y) {
; CHECK-LABEL: @ult_to_slt(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, %y
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 128
%b = xor i8 %y, 128
%cmp = icmp ult i8 %a, %b
ret i1 %cmp
}
define <2 x i1> @ult_to_slt_splat(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @ult_to_slt_splat(
; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128>
; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128>
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 128, i8 128>
%b = xor <2 x i8> %y, <i8 128, i8 128>
%cmp = icmp ult <2 x i8> %a, %b
ret <2 x i1> %cmp
}
; icmp u/s (a ^ maxsignval), (b ^ maxsignval) --> icmp s/u' a, b
define i1 @slt_to_ugt(i8 %x, i8 %y) {
; CHECK-LABEL: @slt_to_ugt(
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 %x, %y
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 127
%b = xor i8 %y, 127
%cmp = icmp slt i8 %a, %b
ret i1 %cmp
}
define <2 x i1> @slt_to_ugt_splat(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @slt_to_ugt_splat(
; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127>
; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127>
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 127, i8 127>
%b = xor <2 x i8> %y, <i8 127, i8 127>
%cmp = icmp slt <2 x i8> %a, %b
ret <2 x i1> %cmp
}
; Make sure that unsigned -> signed works too.
define i1 @ult_to_sgt(i8 %x, i8 %y) {
; CHECK-LABEL: @ult_to_sgt(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, %y
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 127
%b = xor i8 %y, 127
%cmp = icmp ult i8 %a, %b
ret i1 %cmp
}
define <2 x i1> @ult_to_sgt_splat(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @ult_to_sgt_splat(
; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127>
; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127>
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 127, i8 127>
%b = xor <2 x i8> %y, <i8 127, i8 127>
%cmp = icmp ult <2 x i8> %a, %b
ret <2 x i1> %cmp
}
; icmp u/s (a ^ signmask), C --> icmp s/u a, C'
define i1 @sge_to_ugt(i8 %x) {
; CHECK-LABEL: @sge_to_ugt(
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 %x, -114
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 128
%cmp = icmp sge i8 %a, 15
ret i1 %cmp
}
define <2 x i1> @sge_to_ugt_splat(<2 x i8> %x) {
; CHECK-LABEL: @sge_to_ugt_splat(
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> %x, <i8 -114, i8 -114>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 128, i8 128>
%cmp = icmp sge <2 x i8> %a, <i8 15, i8 15>
ret <2 x i1> %cmp
}
; Make sure that unsigned -> signed works too.
define i1 @uge_to_sgt(i8 %x) {
; CHECK-LABEL: @uge_to_sgt(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -114
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 128
%cmp = icmp uge i8 %a, 15
ret i1 %cmp
}
define <2 x i1> @uge_to_sgt_splat(<2 x i8> %x) {
; CHECK-LABEL: @uge_to_sgt_splat(
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -114, i8 -114>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 128, i8 128>
%cmp = icmp uge <2 x i8> %a, <i8 15, i8 15>
ret <2 x i1> %cmp
}
; icmp u/s (a ^ maxsignval), C --> icmp s/u' a, C'
define i1 @sge_to_ult(i8 %x) {
; CHECK-LABEL: @sge_to_ult(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 %x, 113
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 127
%cmp = icmp sge i8 %a, 15
ret i1 %cmp
}
define <2 x i1> @sge_to_ult_splat(<2 x i8> %x) {
; CHECK-LABEL: @sge_to_ult_splat(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> %x, <i8 113, i8 113>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 127, i8 127>
%cmp = icmp sge <2 x i8> %a, <i8 15, i8 15>
ret <2 x i1> %cmp
}
; Make sure that unsigned -> signed works too.
define i1 @uge_to_slt(i8 %x) {
; CHECK-LABEL: @uge_to_slt(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 113
; CHECK-NEXT: ret i1 [[CMP]]
;
%a = xor i8 %x, 127
%cmp = icmp uge i8 %a, 15
ret i1 %cmp
}
define <2 x i1> @uge_to_slt_splat(<2 x i8> %x) {
; CHECK-LABEL: @uge_to_slt_splat(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> %x, <i8 113, i8 113>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%a = xor <2 x i8> %x, <i8 127, i8 127>
%cmp = icmp uge <2 x i8> %a, <i8 15, i8 15>
ret <2 x i1> %cmp
}