From 7ad3dbe83692fa399a790866ca5ab6554f520f4a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 23 May 2017 16:53:05 +0000 Subject: [PATCH] [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 --- .../InstCombine/2008-08-17-ICmpXorSignbit.ll | 87 -------- .../InstCombine/icmp-xor-signbit.ll | 197 ++++++++++++++++++ 2 files changed, 197 insertions(+), 87 deletions(-) delete mode 100644 llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll create mode 100644 llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll diff --git a/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll b/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll deleted file mode 100644 index b91457c79dea..000000000000 --- a/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll +++ /dev/null @@ -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, -; CHECK-NEXT: ret <2 x i1> [[TMP]] -; - %X = xor <2 x i8> %x, - %tmp = icmp uge <2 x i8> %X, - 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, -; CHECK-NEXT: ret <2 x i1> [[TMP]] -; - %X = xor <2 x i8> %x, - %tmp = icmp uge <2 x i8> %X, - ret <2 x i1> %tmp -} - diff --git a/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll b/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll new file mode 100644 index 000000000000..4b4d1ddbc5a8 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll @@ -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, +; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %b = xor <2 x i8> %y, + %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, +; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, +; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %b = xor <2 x i8> %y, + %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, +; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %b = xor <2 x i8> %y, + %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, +; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, +; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %b = xor <2 x i8> %y, + %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, +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %cmp = icmp sge <2 x i8> %a, + 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, +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %cmp = icmp uge <2 x i8> %a, + 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, +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %cmp = icmp sge <2 x i8> %a, + 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, +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %a = xor <2 x i8> %x, + %cmp = icmp uge <2 x i8> %a, + ret <2 x i1> %cmp +} +