257 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i1 @xor_logic_and_logic_or1(i1 %c, i1 %x, i1 %y) {5; CHECK-LABEL: @xor_logic_and_logic_or1(6; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true7; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]8; CHECK-NEXT: ret i1 [[R]]9;10 %o = select i1 %c, i1 true, i1 %y11 %a = select i1 %c, i1 %x, i1 false12 %r = xor i1 %a, %o13 ret i1 %r14}15 16define i1 @xor_logic_and_logic_or2(i1 %c, i1 %x, i1 %y) {17; CHECK-LABEL: @xor_logic_and_logic_or2(18; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true19; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]20; CHECK-NEXT: ret i1 [[R]]21;22 %o = select i1 %y, i1 true, i1 %c23 %a = select i1 %c, i1 %x, i1 false24 %r = xor i1 %a, %o25 ret i1 %r26}27 28define i1 @xor_logic_and_logic_or2_commuted(i1 %c, i1 %x, i1 %y) {29; CHECK-LABEL: @xor_logic_and_logic_or2_commuted(30; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true31; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]32; CHECK-NEXT: ret i1 [[R]]33;34 %o = select i1 %y, i1 true, i1 %c35 %a = select i1 %c, i1 %x, i1 false36 %r = xor i1 %o, %a37 ret i1 %r38}39 40define i1 @xor_logic_and_logic_or3(i1 %c, i1 %x, i1 %y) {41; CHECK-LABEL: @xor_logic_and_logic_or3(42; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]]43; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[X:%.*]], true44; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i1 [[TMP2]], i1 [[Y:%.*]]45; CHECK-NEXT: ret i1 [[R]]46;47 %o = select i1 %y, i1 true, i1 %c48 %a = select i1 %x, i1 %c, i1 false49 %r = xor i1 %a, %o50 ret i1 %r51}52 53define i1 @xor_logic_and_logic_or4(i1 %c, i1 %x, i1 %y) {54; CHECK-LABEL: @xor_logic_and_logic_or4(55; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true56; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]57; CHECK-NEXT: ret i1 [[R]]58;59 %o = select i1 %c, i1 true, i1 %y60 %a = select i1 %x, i1 %c, i1 false61 %r = xor i1 %a, %o62 ret i1 %r63}64 65define <3 x i1> @xor_logic_and_logic_or_vector1(<3 x i1> %c, <3 x i1> %x, <3 x i1> %y) {66; CHECK-LABEL: @xor_logic_and_logic_or_vector1(67; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i1> [[X:%.*]], splat (i1 true)68; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> [[Y:%.*]]69; CHECK-NEXT: ret <3 x i1> [[R]]70;71 %o = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y72 %a = select <3 x i1> %c, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false>73 %r = xor <3 x i1> %a, %o74 ret <3 x i1> %r75}76 77define <3 x i1> @xor_logic_and_logic_or_vector2(<3 x i1> %c, <3 x i1> %x, <3 x i1> %y) {78; CHECK-LABEL: @xor_logic_and_logic_or_vector2(79; CHECK-NEXT: [[TMP1:%.*]] = freeze <3 x i1> [[C:%.*]]80; CHECK-NEXT: [[TMP2:%.*]] = xor <3 x i1> [[X:%.*]], splat (i1 true)81; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP1]], <3 x i1> [[TMP2]], <3 x i1> [[Y:%.*]]82; CHECK-NEXT: ret <3 x i1> [[R]]83;84 %o = select <3 x i1> %y, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %c85 %a = select <3 x i1> %x, <3 x i1> %c, <3 x i1> <i1 false, i1 false, i1 false>86 %r = xor <3 x i1> %a, %o87 ret <3 x i1> %r88}89 90define <3 x i1> @xor_logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %x, <3 x i1> %y) {91; CHECK-LABEL: @xor_logic_and_logic_or_vector_poison1(92; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i1> [[X:%.*]], <i1 true, i1 true, i1 poison>93; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> [[Y:%.*]]94; CHECK-NEXT: ret <3 x i1> [[R]]95;96 %o = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> %y97 %a = select <3 x i1> %c, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false>98 %r = xor <3 x i1> %a, %o99 ret <3 x i1> %r100}101 102define <3 x i1> @xor_logic_and_logic_or_vector_poison2(<3 x i1> %c, <3 x i1> %x, <3 x i1> %y) {103; CHECK-LABEL: @xor_logic_and_logic_or_vector_poison2(104; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i1> [[X:%.*]], splat (i1 true)105; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> [[Y:%.*]]106; CHECK-NEXT: ret <3 x i1> [[R]]107;108 %o = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y109 %a = select <3 x i1> %c, <3 x i1> %x, <3 x i1> <i1 false, i1 poison, i1 false>110 %r = xor <3 x i1> %a, %o111 ret <3 x i1> %r112}113 114define i1 @xor_and_logic_or1(i1 %c, i1 %x, i1 %y) {115; CHECK-LABEL: @xor_and_logic_or1(116; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true117; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]118; CHECK-NEXT: ret i1 [[R]]119;120 %o = select i1 %c, i1 true, i1 %y121 %a = and i1 %c, %x122 %r = xor i1 %a, %o123 ret i1 %r124}125 126define i1 @xor_and_logic_or2(i1 %c, i1 %x, i1 %y) {127; CHECK-LABEL: @xor_and_logic_or2(128; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true129; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]130; CHECK-NEXT: ret i1 [[R]]131;132 %o = select i1 %y, i1 true, i1 %c133 %a = and i1 %x, %c134 %r = xor i1 %a, %o135 ret i1 %r136}137 138define <2 x i1> @xor_and_logic_or_vector(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {139; CHECK-LABEL: @xor_and_logic_or_vector(140; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)141; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[TMP1]], <2 x i1> [[Y:%.*]]142; CHECK-NEXT: ret <2 x i1> [[R]]143;144 %o = select <2 x i1> %c, <2 x i1> <i1 true, i1 true>, <2 x i1> %y145 %a = and <2 x i1> %c, %x146 %r = xor <2 x i1> %a, %o147 ret <2 x i1> %r148}149 150define <2 x i1> @xor_and_logic_or_vector_poison(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {151; CHECK-LABEL: @xor_and_logic_or_vector_poison(152; CHECK-NEXT: [[O:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[Y:%.*]]153; CHECK-NEXT: [[A:%.*]] = and <2 x i1> [[C]], [[X:%.*]]154; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[A]], [[O]]155; CHECK-NEXT: ret <2 x i1> [[R]]156;157 %o = select <2 x i1> %c, <2 x i1> <i1 poison, i1 true>, <2 x i1> %y158 %a = and <2 x i1> %c, %x159 %r = xor <2 x i1> %a, %o160 ret <2 x i1> %r161}162 163define i1 @xor_logic_and_or1(i1 %c, i1 %x, i1 %y) {164; CHECK-LABEL: @xor_logic_and_or1(165; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true166; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]167; CHECK-NEXT: ret i1 [[R]]168;169 %o = or i1 %y, %c170 %a = select i1 %c, i1 %x, i1 false171 %r = xor i1 %a, %o172 ret i1 %r173}174 175define i1 @xor_logic_and_or2(i1 %c, i1 %x, i1 %y) {176; CHECK-LABEL: @xor_logic_and_or2(177; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true178; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]179; CHECK-NEXT: ret i1 [[R]]180;181 %o = or i1 %c, %y182 %a = select i1 %x, i1 %c, i1 false183 %r = xor i1 %a, %o184 ret i1 %r185}186 187define <2 x i1> @xor_logic_and_or_vector(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {188; CHECK-LABEL: @xor_logic_and_or_vector(189; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)190; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[TMP1]], <2 x i1> [[Y:%.*]]191; CHECK-NEXT: ret <2 x i1> [[R]]192;193 %o = or <2 x i1> %y, %c194 %a = select <2 x i1> %c, <2 x i1> %x, <2 x i1> <i1 false, i1 false>195 %r = xor <2 x i1> %a, %o196 ret <2 x i1> %r197}198 199define <2 x i1> @xor_logic_and_or_vector_poison(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) {200; CHECK-LABEL: @xor_logic_and_or_vector_poison(201; CHECK-NEXT: [[O:%.*]] = or <2 x i1> [[Y:%.*]], [[C:%.*]]202; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[C]], <2 x i1> [[X:%.*]], <2 x i1> <i1 poison, i1 false>203; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[A]], [[O]]204; CHECK-NEXT: ret <2 x i1> [[R]]205;206 %o = or <2 x i1> %y, %c207 %a = select <2 x i1> %c, <2 x i1> %x, <2 x i1> <i1 poison, i1 false>208 %r = xor <2 x i1> %a, %o209 ret <2 x i1> %r210}211 212;; even through we save a instruction here, select is heavier than normal213;; and/or/xor on most backend, do we really need to do this transform?214define i1 @xor_and_or(i1 %c, i1 %x, i1 %y) {215; CHECK-LABEL: @xor_and_or(216; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true217; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]218; CHECK-NEXT: ret i1 [[R]]219;220 %o = or i1 %y, %c221 %a = and i1 %c, %x222 %r = xor i1 %a, %o223 ret i1 %r224}225 226;; even though we save a instruction here, select is heavier than normal227;; and/or/xor on most backend, do we really need to do this transform?228define <4 x i1> @xor_and_or_vector(<4 x i1> %c, <4 x i1> %x, <4 x i1> %y) {229; CHECK-LABEL: @xor_and_or_vector(230; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[X:%.*]], splat (i1 true)231; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[TMP1]], <4 x i1> [[Y:%.*]]232; CHECK-NEXT: ret <4 x i1> [[R]]233;234 %o = or <4 x i1> %y, %c235 %a = and <4 x i1> %c, %x236 %r = xor <4 x i1> %a, %o237 ret <4 x i1> %r238}239 240; Negative test, more than one use241define i1 @xor_and_or_negative_oneuse(i1 %c, i1 %x, i1 %y) {242; CHECK-LABEL: @xor_and_or_negative_oneuse(243; CHECK-NEXT: [[O:%.*]] = or i1 [[Y:%.*]], [[C:%.*]]244; CHECK-NEXT: [[A:%.*]] = and i1 [[C]], [[X:%.*]]245; CHECK-NEXT: [[R:%.*]] = xor i1 [[A]], [[O]]246; CHECK-NEXT: call void @use(i1 [[O]])247; CHECK-NEXT: ret i1 [[R]]248;249 %o = or i1 %y, %c250 %a = and i1 %c, %x251 %r = xor i1 %a, %o252 call void @use(i1 %o)253 ret i1 %r254}255 256declare void @use(i1)257