; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s ; select(Y | X == 0, X, Y | X) define i32 @select_or_1(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_1( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[OR]] ; %or = or i32 %y, %x %cmp = icmp eq i32 %or, 0 %ret = select i1 %cmp, i32 %x, i32 %or ret i32 %ret } ; select(Y | X == 0, Y, Y | X) define i32 @select_or_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_2( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[OR]] ; %or = or i32 %y, %x %cmp = icmp eq i32 %or, 0 %ret = select i1 %cmp, i32 %y, i32 %or ret i32 %ret } ; select(Y | X != 0, Y | X, X) define i32 @select_or_3(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_3( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[OR]] ; %or = or i32 %y, %x %cmp = icmp ne i32 %or, 0 %ret = select i1 %cmp, i32 %or, i32 %x ret i32 %ret } ; select(Y | X != 0, Y | X, Y) define i32 @select_or_4(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_4( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[OR]] ; %or = or i32 %y, %x %cmp = icmp ne i32 %or, 0 %ret = select i1 %cmp, i32 %or, i32 %y ret i32 %ret } ; select(Y | X != 0, Y | X, Y) define <4 x i32> @select_or_vec(<4 x i32> %x, <4 x i32> %y) { ; CHECK-LABEL: @select_or_vec( ; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret <4 x i32> [[OR]] ; %or = or <4 x i32> %y, %x %cmp = icmp ne <4 x i32> %or, zeroinitializer %ret = select <4 x i1> %cmp, <4 x i32> %or, <4 x i32> %y ret <4 x i32> %ret } ; select(Y | X == 0, Y | X, Y) define i32 @select_or_not_1(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_not_1( ; CHECK-NEXT: ret i32 [[Y:%.*]] ; %or = or i32 %y, %x %cmp = icmp eq i32 %or, 0 %ret = select i1 %cmp, i32 %or, i32 %y ret i32 %ret } ; select(Y | X != 0, Y, Y | X) define i32 @select_or_not_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_not_2( ; CHECK-NEXT: ret i32 [[Y:%.*]] ; %or = or i32 %y, %x %cmp = icmp ne i32 %or, 0 %ret = select i1 %cmp, i32 %y, i32 %or ret i32 %ret } ; select(Y | X != 1, Y, Y | X) define i32 @select_or_not_3(i32 %x, i32 %y) { ; CHECK-LABEL: @select_or_not_3( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[OR]], 1 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] ; CHECK-NEXT: ret i32 [[RET]] ; %or = or i32 %y, %x %cmp = icmp ne i32 %or, 1 %ret = select i1 %cmp, i32 %y, i32 %or ret i32 %ret } ; select(Y & X == -1, X, Y & X) define i32 @select_and_1(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_1( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[AND]] ; %and = and i32 %y, %x %cmp = icmp eq i32 %and, -1 %ret = select i1 %cmp, i32 %x, i32 %and ret i32 %ret } ; select(Y & X == -1, Y, Y & X) define i32 @select_and_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_2( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[AND]] ; %and = and i32 %y, %x %cmp = icmp eq i32 %and, -1 %ret = select i1 %cmp, i32 %y, i32 %and ret i32 %ret } ; select(Y & X != -1, Y & X, X) define i32 @select_and_3(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_3( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[AND]] ; %and = and i32 %y, %x %cmp = icmp ne i32 %and, -1 %ret = select i1 %cmp, i32 %and, i32 %x ret i32 %ret } ; select(Y & X != -1, Y & X, Y) define i32 @select_and_4(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_4( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[AND]] ; %and = and i32 %y, %x %cmp = icmp ne i32 %and, -1 %ret = select i1 %cmp, i32 %and, i32 %y ret i32 %ret } ; select(Y & X != -1, Y, Y & X) define i32 @select_and_not_1(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_not_1( ; CHECK-NEXT: ret i32 [[Y:%.*]] ; %and = and i32 %y, %x %cmp = icmp eq i32 %and, -1 %ret = select i1 %cmp, i32 %and, i32 %y ret i32 %ret } ; select(Y & X != -1, Y, Y & X) define i32 @select_and_not_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_not_2( ; CHECK-NEXT: ret i32 [[Y:%.*]] ; %and = and i32 %y, %x %cmp = icmp ne i32 %and, -1 %ret = select i1 %cmp, i32 %y, i32 %and ret i32 %ret } ; select(Y & X != 123, Y, Y & X) define i32 @select_and_not_3(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_not_3( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 123 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]] ; CHECK-NEXT: ret i32 [[RET]] ; %and = and i32 %y, %x %cmp = icmp ne i32 %and, 123 %ret = select i1 %cmp, i32 %y, i32 %and ret i32 %ret } ; https://alive2.llvm.org/ce/z/1ILbih define i32 @select_icmp_and_eq(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_eq( ; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp eq i32 %and, -1 %cond = select i1 %tobool, i32 %a, i32 -1 ret i32 %cond } define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_eq_commuted( ; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp eq i32 %and, -1 %cond = select i1 %tobool, i32 %b, i32 -1 ret i32 %cond } ; https://alive2.llvm.org/ce/z/HfYXvx define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) { ; CHECK-LABEL: @select_icmp_and_eq_vec( ; CHECK-NEXT: ret <2 x i16> ; %and = and <2 x i16> %a, %b %tobool = icmp eq <2 x i16> %and, %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> ret <2 x i16> %cond } ; The ne should also be macthed define i32 @select_icmp_and_ne(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_ne( ; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp ne i32 %and, -1 %cond = select i1 %tobool, i32 -1, i32 %a ret i32 %cond } ; Negative test: Incorrect const value for icmp define i32 @select_icmp_and_eq_incorrect_const(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_eq_incorrect_const( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1 ; CHECK-NEXT: ret i32 [[COND]] ; %and = and i32 %a, %b %tobool = icmp eq i32 %and, 0 ; Incorrect const value %cond = select i1 %tobool, i32 %a, i32 -1 ret i32 %cond } ; https://alive2.llvm.org/ce/z/hSyCuR define i32 @select_icmp_or_eq(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_or_eq( ; CHECK-NEXT: ret i32 0 ; %or = or i32 %a, %b %tobool = icmp eq i32 %or, 0 %cond = select i1 %tobool, i32 %a, i32 0 ret i32 %cond } define i32 @select_icmp_or_eq_commuted(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_or_eq_commuted( ; CHECK-NEXT: ret i32 0 ; %or = or i32 %a, %b %tobool = icmp eq i32 %or, 0 %cond = select i1 %tobool, i32 %b, i32 0 ret i32 %cond } ; https://alive2.llvm.org/ce/z/S_pQek define <2 x i16> @select_icmp_or_eq_vec(<2 x i16> %a, <2 x i16> %b) { ; CHECK-LABEL: @select_icmp_or_eq_vec( ; CHECK-NEXT: ret <2 x i16> zeroinitializer ; %or = or <2 x i16> %a, %b %tobool = icmp eq <2 x i16> %or, %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> zeroinitializer ret <2 x i16> %cond } ; The ne will also be matched define i32 @select_icmp_or_ne(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_or_ne( ; CHECK-NEXT: ret i32 0 ; %or = or i32 %a, %b %tobool = icmp ne i32 %or, 0 %cond = select i1 %tobool, i32 0, i32 %a ret i32 %cond } ; Negative test: Incorrect const value for icmp define i32 @select_icmp_or_eq_incorrect_const(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_or_eq_incorrect_const( ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[OR]], -1 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 0 ; CHECK-NEXT: ret i32 [[COND]] ; %or = or i32 %a, %b %tobool = icmp eq i32 %or, -1 %cond = select i1 %tobool, i32 %a, i32 0 ret i32 %cond }