[llvm] r329198 - [InstCombine] [NFC] Add tests for getting rid of select of bittest (PR36950 / PR17564)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 4 07:10:13 PDT 2018


Author: lebedevri
Date: Wed Apr  4 07:10:13 2018
New Revision: 329198

URL: http://llvm.org/viewvc/llvm-project?rev=329198&view=rev
Log:
[InstCombine] [NFC] Add tests for getting rid of select of bittest (PR36950 / PR17564)

Summary: See [[ https://bugs.llvm.org/show_bug.cgi?id=36950 | PR36950 ]], [[ https://bugs.llvm.org/show_bug.cgi?id=17564 | PR17564 ]], D45065, D45108

Reviewers: spatel, craig.topper

Reviewed By: spatel

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D45107

Added:
    llvm/trunk/test/Transforms/InstCombine/select-of-bittest.ll

Added: llvm/trunk/test/Transforms/InstCombine/select-of-bittest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-of-bittest.ll?rev=329198&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-of-bittest.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/select-of-bittest.ll Wed Apr  4 07:10:13 2018
@@ -0,0 +1,464 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; https://bugs.llvm.org/show_bug.cgi?id=36950
+
+; These all should be just and+icmp, there should be no select.
+; https://rise4fun.com/Alive/uiH
+
+define i32 @and_lshr_and(i32) {
+; CHECK-LABEL: @and_lshr_and(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = and i32 %0, 1
+  %3 = icmp eq i32 %2, 0
+  %4 = lshr i32 %0, 1
+  %5 = and i32 %4, 1
+  %6 = select i1 %3, i32 %5, i32 1
+  ret i32 %6
+}
+
+define <2 x i32> @and_lshr_and_splatvec(<2 x i32>) {
+; CHECK-LABEL: @and_lshr_and_splatvec(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <2 x i32> [[TMP4]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP5]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
+;
+  %2 = and <2 x i32> %0, <i32 1, i32 1>
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = lshr <2 x i32> %0, <i32 1, i32 1>
+  %5 = and <2 x i32> %4, <i32 1, i32 1>
+  %6 = select <2 x i1> %3, <2 x i32> %5, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %6
+}
+
+define <2 x i32> @and_lshr_and_vec_v0(<2 x i32>) {
+; CHECK-LABEL: @and_lshr_and_vec_v0(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 1, i32 4>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <2 x i32> [[TMP4]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP5]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
+;
+  %2 = and <2 x i32> %0, <i32 1, i32 4> ; mask is not splat
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = lshr <2 x i32> %0, <i32 1, i32 1>
+  %5 = and <2 x i32> %4, <i32 1, i32 1>
+  %6 = select <2 x i1> %3, <2 x i32> %5, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %6
+}
+
+define <2 x i32> @and_lshr_and_vec_v1(<2 x i32>) {
+; CHECK-LABEL: @and_lshr_and_vec_v1(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr <2 x i32> [[TMP0]], <i32 1, i32 2>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <2 x i32> [[TMP4]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP5]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
+;
+  %2 = and <2 x i32> %0, <i32 1, i32 1>
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = lshr <2 x i32> %0, <i32 1, i32 2> ; shift is not splat
+  %5 = and <2 x i32> %4, <i32 1, i32 1>
+  %6 = select <2 x i1> %3, <2 x i32> %5, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %6
+}
+
+define <2 x i32> @and_lshr_and_vec_v2(<2 x i32>) {
+; CHECK-LABEL: @and_lshr_and_vec_v2(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 8, i32 1>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr <2 x i32> [[TMP0]], <i32 2, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <2 x i32> [[TMP4]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP5]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
+;
+  %2 = and <2 x i32> %0, <i32 8, i32 1> ; mask is not splat
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = lshr <2 x i32> %0, <i32 2, i32 1> ; shift is not splat
+  %5 = and <2 x i32> %4, <i32 1, i32 1>
+  %6 = select <2 x i1> %3, <2 x i32> %5, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %6
+}
+
+define <3 x i32> @and_lshr_and_vec_undef(<3 x i32>) {
+; CHECK-LABEL: @and_lshr_and_vec_undef(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP0:%.*]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <3 x i32> [[TMP2]], <i32 0, i32 undef, i32 0>
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr <3 x i32> [[TMP0]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <3 x i32> [[TMP4]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <3 x i1> [[TMP3]], <3 x i32> [[TMP5]], <3 x i32> <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    ret <3 x i32> [[TMP6]]
+;
+  %2 = and <3 x i32> %0, <i32 1, i32 undef, i32 1>
+  %3 = icmp eq <3 x i32> %2, <i32 0, i32 undef, i32 0>
+  %4 = lshr <3 x i32> %0, <i32 1, i32 undef, i32 1>
+  %5 = and <3 x i32> %4, <i32 1, i32 undef, i32 1>
+  %6 = select <3 x i1> %3, <3 x i32> %5, <3 x i32> <i32 1, i32 undef, i32 1>
+  ret <3 x i32> %6
+}
+
+define i32 @and_and(i32) {
+; CHECK-LABEL: @and_and(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i32 [[TMP4]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %2 = and i32 %0, 2
+  %3 = icmp eq i32 %2, 0
+  %4 = and i32 %0, 1
+  %5 = select i1 %3, i32 %4, i32 1
+  ret i32 %5
+}
+
+define <2 x i32> @and_and_splatvec(<2 x i32>) {
+; CHECK-LABEL: @and_and_splatvec(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 2, i32 2>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = and <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP4]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
+;
+  %2 = and <2 x i32> %0, <i32 2, i32 2>
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = and <2 x i32> %0, <i32 1, i32 1>
+  %5 = select <2 x i1> %3, <2 x i32> %4, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %5
+}
+
+define <2 x i32> @and_and_vec(<2 x i32>) {
+; CHECK-LABEL: @and_and_vec(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP0:%.*]], <i32 6, i32 2>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = and <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP4]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
+;
+  %2 = and <2 x i32> %0, <i32 6, i32 2> ; mask is not splat
+  %3 = icmp eq <2 x i32> %2, <i32 0, i32 0>
+  %4 = and <2 x i32> %0, <i32 1, i32 1>
+  %5 = select <2 x i1> %3, <2 x i32> %4, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %5
+}
+
+define <3 x i32> @and_and_vec_undef(<3 x i32>) {
+; CHECK-LABEL: @and_and_vec_undef(
+; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP0:%.*]], <i32 2, i32 undef, i32 2>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq <3 x i32> [[TMP2]], <i32 0, i32 undef, i32 0>
+; CHECK-NEXT:    [[TMP4:%.*]] = and <3 x i32> [[TMP0]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = select <3 x i1> [[TMP3]], <3 x i32> [[TMP4]], <3 x i32> <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    ret <3 x i32> [[TMP5]]
+;
+  %2 = and <3 x i32> %0, <i32 2, i32 undef, i32 2>
+  %3 = icmp eq <3 x i32> %2, <i32 0, i32 undef, i32 0>
+  %4 = and <3 x i32> %0, <i32 1, i32 undef, i32 1>
+  %5 = select <3 x i1> %3, <3 x i32> %4, <3 x i32> <i32 1, i32 undef, i32 1>
+  ret <3 x i32> %5
+}
+
+; ============================================================================ ;
+; Mask can be a variable, too.
+; ============================================================================ ;
+
+define i32 @f_var0(i32, i32) {
+; CHECK-LABEL: @f_var0(
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[TMP5]], 1
+; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP4]], i32 [[TMP6]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP7]]
+;
+  %3 = and i32 %0, %1
+  %4 = icmp eq i32 %3, 0
+  %5 = lshr i32 %0, 1
+  %6 = and i32 %5, 1
+  %7 = select i1 %4, i32 %6, i32 1
+  ret i32 %7
+}
+
+define <2 x i32> @f_var0_splatvec(<2 x i32>, <2 x i32>) {
+; CHECK-LABEL: @f_var0_splatvec(
+; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <2 x i32> [[TMP3]], zeroinitializer
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = and <2 x i32> [[TMP5]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP7:%.*]] = select <2 x i1> [[TMP4]], <2 x i32> [[TMP6]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP7]]
+;
+  %3 = and <2 x i32> %0, %1
+  %4 = icmp eq <2 x i32> %3, <i32 0, i32 0>
+  %5 = lshr <2 x i32> %0, <i32 1, i32 1>
+  %6 = and <2 x i32> %5, <i32 1, i32 1>
+  %7 = select <2 x i1> %4, <2 x i32> %6, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %7
+}
+
+define <2 x i32> @f_var0_vec(<2 x i32>, <2 x i32>) {
+; CHECK-LABEL: @f_var0_vec(
+; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <2 x i32> [[TMP3]], zeroinitializer
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr <2 x i32> [[TMP0]], <i32 1, i32 2>
+; CHECK-NEXT:    [[TMP6:%.*]] = and <2 x i32> [[TMP5]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP7:%.*]] = select <2 x i1> [[TMP4]], <2 x i32> [[TMP6]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP7]]
+;
+  %3 = and <2 x i32> %0, %1
+  %4 = icmp eq <2 x i32> %3, <i32 0, i32 0>
+  %5 = lshr <2 x i32> %0, <i32 1, i32 2> ; shift is not splat
+  %6 = and <2 x i32> %5, <i32 1, i32 1>
+  %7 = select <2 x i1> %4, <2 x i32> %6, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %7
+}
+
+define <3 x i32> @f_var0_vec_undef(<3 x i32>, <3 x i32>) {
+; CHECK-LABEL: @f_var0_vec_undef(
+; CHECK-NEXT:    [[TMP3:%.*]] = and <3 x i32> [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <3 x i32> [[TMP3]], <i32 0, i32 undef, i32 0>
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr <3 x i32> [[TMP0]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = and <3 x i32> [[TMP5]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP7:%.*]] = select <3 x i1> [[TMP4]], <3 x i32> [[TMP6]], <3 x i32> <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    ret <3 x i32> [[TMP7]]
+;
+  %3 = and <3 x i32> %0, %1
+  %4 = icmp eq <3 x i32> %3, <i32 0, i32 undef, i32 0>
+  %5 = lshr <3 x i32> %0, <i32 1, i32 undef, i32 1>
+  %6 = and <3 x i32> %5, <i32 1, i32 undef, i32 1>
+  %7 = select <3 x i1> %4, <3 x i32> %6, <3 x i32> <i32 1, i32 undef, i32 1>
+  ret <3 x i32> %7
+}
+
+define i32 @f_var1(i32, i32) {
+; CHECK-LABEL: @f_var1(
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP4]], i32 [[TMP5]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %3 = and i32 %0, %1
+  %4 = icmp eq i32 %3, 0
+  %5 = and i32 %0, 1
+  %6 = select i1 %4, i32 %5, i32 1
+  ret i32 %6
+}
+
+define <2 x i32> @f_var1_vec(<2 x i32>, <2 x i32>) {
+; CHECK-LABEL: @f_var1_vec(
+; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i32> [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <2 x i32> [[TMP3]], zeroinitializer
+; CHECK-NEXT:    [[TMP5:%.*]] = and <2 x i32> [[TMP0]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <2 x i1> [[TMP4]], <2 x i32> [[TMP5]], <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP6]]
+;
+  %3 = and <2 x i32> %0, %1
+  %4 = icmp eq <2 x i32> %3, <i32 0, i32 0>
+  %5 = and <2 x i32> %0, <i32 1, i32 1>
+  %6 = select <2 x i1> %4, <2 x i32> %5, <2 x i32> <i32 1, i32 1>
+  ret <2 x i32> %6
+}
+
+define <3 x i32> @f_var1_vec_undef(<3 x i32>, <3 x i32>) {
+; CHECK-LABEL: @f_var1_vec_undef(
+; CHECK-NEXT:    [[TMP3:%.*]] = and <3 x i32> [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq <3 x i32> [[TMP3]], <i32 0, i32 undef, i32 0>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <3 x i32> [[TMP0]], <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    [[TMP6:%.*]] = select <3 x i1> [[TMP4]], <3 x i32> [[TMP5]], <3 x i32> <i32 1, i32 undef, i32 1>
+; CHECK-NEXT:    ret <3 x i32> [[TMP6]]
+;
+  %3 = and <3 x i32> %0, %1
+  %4 = icmp eq <3 x i32> %3, <i32 0, i32 undef, i32 0>
+  %5 = and <3 x i32> %0, <i32 1, i32 undef, i32 1>
+  %6 = select <3 x i1> %4, <3 x i32> %5, <3 x i32> <i32 1, i32 undef, i32 1>
+  ret <3 x i32> %6
+}
+
+; ============================================================================ ;
+; Negative tests. Should not be folded.
+; ============================================================================ ;
+
+; Different variables are used
+
+define i32 @n0(i32, i32) {
+; CHECK-LABEL: @n0(
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr i32 [[TMP1:%.*]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[TMP5]], 1
+; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP4]], i32 [[TMP6]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP7]]
+;
+  %3 = and i32 %0, 1
+  %4 = icmp eq i32 %3, 0
+  %5 = lshr i32 %1, 1 ; works on %1 instead of %0
+  %6 = and i32 %5, 1
+  %7 = select i1 %4, i32 %6, i32 1
+  ret i32 %7
+}
+
+define i32 @n1(i32, i32) {
+; CHECK-LABEL: @n1(
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP0:%.*]], 2
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP1:%.*]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP4]], i32 [[TMP5]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %3 = and i32 %0, 2
+  %4 = icmp eq i32 %3, 0
+  %5 = and i32 %1, 1 ; works on %1 instead of %0
+  %6 = select i1 %4, i32 %5, i32 1
+  ret i32 %6
+}
+
+; False-value is not 1
+
+define i32 @n2(i32) {
+; CHECK-LABEL: @n2(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[TMP0]], 2
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 0
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = and i32 %0, 1
+  %3 = icmp eq i32 %2, 0
+  %4 = lshr i32 %0, 2
+  %5 = and i32 %4, 1
+  %6 = select i1 %3, i32 %5, i32 0 ; 0 instead of 1
+  ret i32 %6
+}
+
+define i32 @n3(i32) {
+; CHECK-LABEL: @n3(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i32 [[TMP4]], i32 0
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %2 = and i32 %0, 2
+  %3 = icmp eq i32 %2, 0
+  %4 = and i32 %0, 1
+  %5 = select i1 %3, i32 %4, i32 0 ; 0 instead of 1
+  ret i32 %5
+}
+
+; Mask of second and is not one
+
+define i32 @n4(i32) {
+; CHECK-LABEL: @n4(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[TMP0]], 2
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 2
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = and i32 %0, 1
+  %3 = icmp eq i32 %2, 0
+  %4 = lshr i32 %0, 2
+  %5 = and i32 %4, 2 ; 2 instead of 1
+  %6 = select i1 %3, i32 %5, i32 1
+  ret i32 %6
+}
+
+define i32 @n5(i32) {
+; CHECK-LABEL: @n5(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP0]], 2
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i32 [[TMP4]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %2 = and i32 %0, 2
+  %3 = icmp eq i32 %2, 0
+  %4 = and i32 %0, 2 ; 2 instead of 1
+  %5 = select i1 %3, i32 %4, i32 1
+  ret i32 %5
+}
+
+; Wrong icmp pred
+
+define i32 @n6(i32) {
+; CHECK-LABEL: @n6(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[TMP0]], 2
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 1, i32 [[TMP5]]
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = and i32 %0, 1
+  %3 = icmp ne i32 %2, 0 ; ne, not eq
+  %4 = lshr i32 %0, 2
+  %5 = and i32 %4, 1
+  %6 = select i1 %3, i32 %5, i32 1
+  ret i32 %6
+}
+
+define i32 @n7(i32) {
+; CHECK-LABEL: @n7(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = and i32 [[TMP0]], 1
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i32 1, i32 [[TMP4]]
+; CHECK-NEXT:    ret i32 [[TMP5]]
+;
+  %2 = and i32 %0, 2
+  %3 = icmp ne i32 %2, 0 ; ne, not eq
+  %4 = and i32 %0, 1
+  %5 = select i1 %3, i32 %4, i32 1
+  ret i32 %5
+}
+
+; icmp second operand is not zero
+
+define i32 @n8(i32) {
+; CHECK-LABEL: @n8(
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i32 [[TMP0]], 2
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP4]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP3]], i32 1, i32 [[TMP5]]
+; CHECK-NEXT:    ret i32 [[TMP6]]
+;
+  %2 = and i32 %0, 1
+  %3 = icmp eq i32 %2, 1 ; 1, not 0
+  %4 = lshr i32 %0, 2
+  %5 = and i32 %4, 1
+  %6 = select i1 %3, i32 %5, i32 1
+  ret i32 %6
+}
+
+; Shift not by a constant
+
+define i32 @n9(i32, i32) {
+; CHECK-LABEL: @n9(
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr i32 [[TMP0]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP6:%.*]] = and i32 [[TMP5]], 1
+; CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP4]], i32 [[TMP6]], i32 1
+; CHECK-NEXT:    ret i32 [[TMP7]]
+;
+  %3 = and i32 %0, 1
+  %4 = icmp eq i32 %3, 0
+  %5 = lshr i32 %0, %1 ; %1, should be a constant
+  %6 = and i32 %5, 1
+  %7 = select i1 %4, i32 %6, i32 1
+  ret i32 %7
+}




More information about the llvm-commits mailing list