598 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare void @use.i1(i1)5declare void @use.i8(i8)6 7; Basic test8 9define i8 @andcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {10; CHECK-LABEL: @andcond(11; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]]12; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]]13; CHECK-NEXT: ret i8 [[OUTER_SEL]]14;15 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond16 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval17 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel18 ret i8 %outer.sel19}20define i8 @orcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {21; CHECK-LABEL: @orcond(22; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]]23; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]24; CHECK-NEXT: ret i8 [[OUTER_SEL]]25;26 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond27 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval28 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval29 ret i8 %outer.sel30}31 32; Extra use tests (basic test, no inversions)33 34define i8 @andcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {35; CHECK-LABEL: @andcond.extrause0(36; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false37; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])38; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]]39; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]]40; CHECK-NEXT: ret i8 [[OUTER_SEL]]41;42 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false43 call void @use.i1(i1 %outer.cond)44 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval45 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel46 ret i8 %outer.sel47}48define i8 @orcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {49; CHECK-LABEL: @orcond.extrause0(50; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]]51; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])52; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND]], i8 [[INNER_SEL_FALSEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]]53; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]54; CHECK-NEXT: ret i8 [[OUTER_SEL]]55;56 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond57 call void @use.i1(i1 %outer.cond)58 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval59 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval60 ret i8 %outer.sel61}62 63define i8 @andcond.extrause1(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {64; CHECK-LABEL: @andcond.extrause1(65; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]66; CHECK-NEXT: call void @use.i8(i8 [[TMP1]])67; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL]]68; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL]]69; CHECK-NEXT: ret i8 [[OUTER_SEL]]70;71 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false72 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval73 call void @use.i8(i8 %inner.sel)74 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel75 ret i8 %outer.sel76}77define i8 @orcond.extrause1(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {78; CHECK-LABEL: @orcond.extrause1(79; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]80; CHECK-NEXT: call void @use.i8(i8 [[TMP1]])81; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_FALSEVAL]], i8 [[OUTER_SEL_FALSEVAL:%.*]]82; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL]], i8 [[INNER_SEL]]83; CHECK-NEXT: ret i8 [[OUTER_SEL]]84;85 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond86 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval87 call void @use.i8(i8 %inner.sel)88 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval89 ret i8 %outer.sel90}91 92define i8 @andcond.extrause2(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {93; CHECK-LABEL: @andcond.extrause2(94; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false95; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])96; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]97; CHECK-NEXT: call void @use.i8(i8 [[INNER_SEL]])98; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]99; CHECK-NEXT: ret i8 [[OUTER_SEL]]100;101 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false102 call void @use.i1(i1 %outer.cond)103 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval104 call void @use.i8(i8 %inner.sel)105 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel106 ret i8 %outer.sel107}108define i8 @orcond.extrause2(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {109; CHECK-LABEL: @orcond.extrause2(110; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]]111; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])112; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]113; CHECK-NEXT: call void @use.i8(i8 [[INNER_SEL]])114; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]]115; CHECK-NEXT: ret i8 [[OUTER_SEL]]116;117 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond118 call void @use.i1(i1 %outer.cond)119 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval120 call void @use.i8(i8 %inner.sel)121 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval122 ret i8 %outer.sel123}124 125; Mismatched 'common' cond126 127define i8 @andcond.different.inner.cond(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {128; CHECK-LABEL: @andcond.different.inner.cond(129; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND_V0:%.*]], i1 [[ALT_COND:%.*]], i1 false130; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND_V1:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]131; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]132; CHECK-NEXT: ret i8 [[OUTER_SEL]]133;134 135 %outer.cond = select i1 %inner.cond.v0, i1 %alt.cond, i1 false136 %inner.sel = select i1 %inner.cond.v1, i8 %inner.sel.trueval, i8 %inner.sel.falseval137 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel138 ret i8 %outer.sel139}140define i8 @orcond.different.inner.cond(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {141; CHECK-LABEL: @orcond.different.inner.cond(142; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND_V0:%.*]], i1 true, i1 [[ALT_COND:%.*]]143; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND_V1:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]144; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]]145; CHECK-NEXT: ret i8 [[OUTER_SEL]]146;147 %outer.cond = select i1 %inner.cond.v0, i1 true, i1 %alt.cond148 %inner.sel = select i1 %inner.cond.v1, i8 %inner.sel.trueval, i8 %inner.sel.falseval149 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval150 ret i8 %outer.sel151}152 153define i1 @andcond.different.inner.cond.both.inverted(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {154; CHECK-LABEL: @andcond.different.inner.cond.both.inverted(155; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND_V0:%.*]], true156; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false157; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true158; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false159; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]]160; CHECK-NEXT: ret i1 [[OUTER_SEL]]161;162 %not.inner.cond.0 = xor i1 %inner.cond.v0, -1163 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond164 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1165 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false166 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel167 ret i1 %outer.sel168}169define i1 @orcond.different.inner.cond.both.inverted(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {170; CHECK-LABEL: @orcond.different.inner.cond.both.inverted(171; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND_V0:%.*]], true172; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[ALT_COND:%.*]]173; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true174; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]]175; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[INNER_SEL]], i1 [[OUTER_SEL_FALSEVAL:%.*]]176; CHECK-NEXT: ret i1 [[OUTER_SEL]]177;178 %not.inner.cond.0 = xor i1 %inner.cond.v0, -1179 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond180 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1181 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval182 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval183 ret i1 %outer.sel184}185 186define i1 @andcond.different.inner.cond.inverted.in.outer.cond(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {187; CHECK-LABEL: @andcond.different.inner.cond.inverted.in.outer.cond(188; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND_V0:%.*]], true189; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false190; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND_V1:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false191; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]]192; CHECK-NEXT: ret i1 [[OUTER_SEL]]193;194 %not.inner.cond.0 = xor i1 %inner.cond.v0, -1195 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond196 %inner.sel = select i1 %inner.cond.v1, i1 %inner.sel.falseval, i1 false197 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel198 ret i1 %outer.sel199}200define i1 @orcond.different.inner.cond.inverted.in.outer.cond(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {201; CHECK-LABEL: @orcond.different.inner.cond.inverted.in.outer.cond(202; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND_V0:%.*]], true203; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[ALT_COND:%.*]]204; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND_V1:%.*]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]]205; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[INNER_SEL]], i1 [[OUTER_SEL_FALSEVAL:%.*]]206; CHECK-NEXT: ret i1 [[OUTER_SEL]]207;208 %not.inner.cond.0 = xor i1 %inner.cond.v0, -1209 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond210 %inner.sel = select i1 %inner.cond.v1, i1 true, i1 %inner.sel.trueval211 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval212 ret i1 %outer.sel213}214 215define i1 @andcond.different.inner.cond.inverted.in.inner.sel(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {216; CHECK-LABEL: @andcond.different.inner.cond.inverted.in.inner.sel(217; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND_V0:%.*]], i1 [[ALT_COND:%.*]], i1 false218; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true219; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false220; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]]221; CHECK-NEXT: ret i1 [[OUTER_SEL]]222;223 %outer.cond = select i1 %inner.cond.v0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond224 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1225 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false226 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel227 ret i1 %outer.sel228}229define i1 @orcond.different.inner.cond.inverted.in.inner.sel(i1 %inner.cond.v0, i1 %inner.cond.v1, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {230; CHECK-LABEL: @orcond.different.inner.cond.inverted.in.inner.sel(231; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND_V0:%.*]], i1 true, i1 [[ALT_COND:%.*]]232; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true233; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]]234; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[INNER_SEL]], i1 [[OUTER_SEL_FALSEVAL:%.*]]235; CHECK-NEXT: ret i1 [[OUTER_SEL]]236;237 %outer.cond = select i1 %inner.cond.v0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond238 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1239 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval240 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval241 ret i1 %outer.sel242}243 244; Not an inversion245; Based on reproduced from https://reviews.llvm.org/D139275#4001580246define i8 @D139275_c4001580(i1 %c0, i1 %c1, i1 %c2, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {247; CHECK-LABEL: @D139275_c4001580(248; CHECK-NEXT: [[INNER_COND:%.*]] = xor i1 [[C0:%.*]], [[C1:%.*]]249; CHECK-NEXT: [[OUTER_COND:%.*]] = and i1 [[C2:%.*]], [[C1]]250; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]251; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]252; CHECK-NEXT: ret i8 [[OUTER_SEL]]253;254 %inner.cond = xor i1 %c0, %c1255 %outer.cond = and i1 %c2, %c1256 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval257 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel258 ret i8 %outer.sel259}260 261; Tests with intervening inversions262 263; In %outer.sel, %outer.cond is inverted264define i1 @andcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {265; CHECK-LABEL: @andcond.001.inv.outer.cond(266; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true267; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false268; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL:%.*]]269; CHECK-NEXT: ret i1 [[OUTER_SEL]]270;271 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond272 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval273 %not.outer.cond = xor i1 %outer.cond, -1274 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false275 ret i1 %outer.sel276}277define i1 @orcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {278; CHECK-LABEL: @orcond.001.inv.outer.cond(279; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true280; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 true, i1 [[INNER_SEL_FALSEVAL:%.*]]281; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]]282; CHECK-NEXT: ret i1 [[OUTER_SEL]]283;284 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond285 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval286 %not.outer.cond = xor i1 %outer.cond, -1287 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel288 ret i1 %outer.sel289}290 291; In %inner.sel, %inner.cond is inverted292define i1 @andcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {293; CHECK-LABEL: @andcond.010.inv.inner.cond.in.inner.sel(294; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 false295; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL:%.*]]296; CHECK-NEXT: ret i1 [[OUTER_SEL]]297;298 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond299 %not.inner.cond = xor i1 %inner.cond, -1300 %inner.sel = select i1 %not.inner.cond, i1 %inner.sel.falseval, i1 false301 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel302 ret i1 %outer.sel303}304define i1 @orcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {305; CHECK-LABEL: @orcond.010.inv.inner.cond.in.inner.sel(306; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 true, i1 [[OUTER_SEL_FALSEVAL:%.*]]307; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]]308; CHECK-NEXT: ret i1 [[OUTER_SEL]]309;310 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond311 %not.inner.cond = xor i1 %inner.cond, -1312 %inner.sel = select i1 %not.inner.cond, i1 true, i1 %inner.sel.trueval313 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval314 ret i1 %outer.sel315}316 317; In %outer.cond, %inner.cond is inverted318define i8 @andcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) {319; CHECK-LABEL: @andcond.100.inv.inner.cond.in.outer.cond(320; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]]321; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]]322; CHECK-NEXT: ret i8 [[OUTER_SEL]]323;324 %not.inner.cond = xor i1 %inner.cond, -1325 %outer.cond = select i1 %not.inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond326 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval327 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel328 ret i8 %outer.sel329}330define i8 @orcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) {331; CHECK-LABEL: @orcond.100.inv.inner.cond.in.outer.cond(332; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]]333; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]]334; CHECK-NEXT: ret i8 [[OUTER_SEL]]335;336 %not.inner.cond = xor i1 %inner.cond, -1337 %outer.cond = select i1 %not.inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond338 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval339 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval340 ret i8 %outer.sel341}342 343; In %outer.sel, %outer.cond is inverted344; In %inner.sel, %inner.cond is inverted345define i1 @andcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {346; CHECK-LABEL: @andcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(347; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true348; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND]], i1 true, i1 [[INNER_SEL_FALSEVAL:%.*]]349; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])350; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true351; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_FALSEVAL]], i1 false352; CHECK-NEXT: [[NOT_INNER_COND1:%.*]] = xor i1 [[INNER_COND]], true353; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND1]], i1 true, i1 [[INNER_SEL]]354; CHECK-NEXT: ret i1 [[OUTER_SEL]]355;356 %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond357 %not.inner.cond = xor i1 %inner.cond, -1358 %inner.sel = select i1 %not.inner.cond, i1 true, i1 %inner.sel.falseval359 %not.outer.cond = xor i1 %outer.cond, -1360 call void @use.i1(i1 %inner.sel)361 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false362 ret i1 %outer.sel363}364define i1 @orcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {365; CHECK-LABEL: @orcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(366; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true367; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false368; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])369; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true370; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 true, i1 [[INNER_SEL_TRUEVAL]]371; CHECK-NEXT: [[NOT_INNER_COND1:%.*]] = xor i1 [[INNER_COND]], true372; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND1]], i1 [[INNER_SEL]], i1 false373; CHECK-NEXT: ret i1 [[OUTER_SEL]]374;375 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond376 %not.inner.cond = xor i1 %inner.cond, -1377 %inner.sel = select i1 %not.inner.cond, i1 %inner.sel.trueval, i1 false378 call void @use.i1(i1 %inner.sel)379 %not.outer.cond = xor i1 %outer.cond, -1380 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel381 ret i1 %outer.sel382}383 384; In %outer.sel, %outer.cond is inverted385; In %outer.cond, %inner.cond is inverted386define i1 @andcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {387; CHECK-LABEL: @andcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(388; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]]389; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])390; CHECK-NEXT: [[ALT_COND_NOT:%.*]] = xor i1 [[ALT_COND:%.*]], true391; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND_NOT]], i1 [[INNER_SEL_FALSEVAL]], i1 false392; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL_TRUEVAL]], i1 [[INNER_SEL]]393; CHECK-NEXT: ret i1 [[OUTER_SEL]]394;395 %not.inner.cond = xor i1 %inner.cond, -1396 %outer.cond = select i1 %not.inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond397 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval398 call void @use.i1(i1 %inner.sel)399 %not.outer.cond = xor i1 %outer.cond, -1400 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false401 ret i1 %outer.sel402}403define i1 @orcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {404; CHECK-LABEL: @orcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(405; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]]406; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])407; CHECK-NEXT: [[ALT_COND_NOT:%.*]] = xor i1 [[ALT_COND:%.*]], true408; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND_NOT]], i1 true, i1 [[INNER_SEL_TRUEVAL]]409; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL]]410; CHECK-NEXT: ret i1 [[OUTER_SEL]]411;412 %not.inner.cond = xor i1 %inner.cond, -1413 %outer.cond = select i1 %not.inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond414 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval415 call void @use.i1(i1 %inner.sel)416 %not.outer.cond = xor i1 %outer.cond, -1417 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel418 ret i1 %outer.sel419}420 421; In %inner.sel, %inner.cond is inverted422; In %outer.cond, %inner.cond is inverted423define i1 @andcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {424; CHECK-LABEL: @andcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(425; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true426; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]]427; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[INNER_SEL]], i1 false428; CHECK-NEXT: ret i1 [[OUTER_SEL]]429;430 %not.inner.cond.0 = xor i1 %inner.cond, -1431 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond432 %not.inner.cond.1 = xor i1 %inner.cond, -1433 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false434 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel435 ret i1 %outer.sel436}437define i1 @orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {438; CHECK-LABEL: @orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(439; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true440; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[OUTER_SEL_FALSEVAL:%.*]]441; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[INNER_SEL]]442; CHECK-NEXT: ret i1 [[OUTER_SEL]]443;444 %not.inner.cond.0 = xor i1 %inner.cond, -1445 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond446 %not.inner.cond.1 = xor i1 %inner.cond, -1447 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval448 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval449 ret i1 %outer.sel450}451 452; In %outer.sel, %outer.cond is inverted453; In %inner.sel, %inner.cond is inverted454; In %outer.cond, %inner.cond is inverted455define i1 @andcond.111.inv.all.conds(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) {456; CHECK-LABEL: @andcond.111.inv.all.conds(457; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true458; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false459; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])460; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND]], true461; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false462; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])463; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[INNER_COND]], i1 true, i1 [[ALT_COND]]464; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true465; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[TMP3]], i1 [[INNER_SEL_FALSEVAL]], i1 false466; CHECK-NEXT: ret i1 [[OUTER_SEL]]467;468 %not.inner.cond.0 = xor i1 %inner.cond, -1469 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond470 call void @use.i1(i1 %outer.cond)471 %not.inner.cond.1 = xor i1 %inner.cond, -1472 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false473 call void @use.i1(i1 %inner.sel)474 %not.outer.cond = xor i1 %outer.cond, -1475 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false476 ret i1 %outer.sel477}478define i1 @orcond.111.inv.all.conds(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) {479; CHECK-LABEL: @orcond.111.inv.all.conds(480; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true481; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[ALT_COND:%.*]]482; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]])483; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND]], true484; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]]485; CHECK-NEXT: call void @use.i1(i1 [[TMP1]])486; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[INNER_COND]], i1 [[ALT_COND]], i1 false487; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true488; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[TMP3]], i1 true, i1 [[INNER_SEL_TRUEVAL]]489; CHECK-NEXT: ret i1 [[OUTER_SEL]]490;491 %not.inner.cond.0 = xor i1 %inner.cond, -1492 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond493 call void @use.i1(i1 %outer.cond)494 %not.inner.cond.1 = xor i1 %inner.cond, -1495 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval496 call void @use.i1(i1 %inner.sel)497 %not.outer.cond = xor i1 %outer.cond, -1498 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel499 ret i1 %outer.sel500}501 502define i8 @test_implied_true(i8 %x) {503; CHECK-LABEL: @test_implied_true(504; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X:%.*]], 0505; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 0, i8 20506; CHECK-NEXT: ret i8 [[SEL2]]507;508 %cmp1 = icmp slt i8 %x, 10509 %cmp2 = icmp slt i8 %x, 0510 %sel1 = select i1 %cmp1, i8 0, i8 5511 %sel2 = select i1 %cmp2, i8 %sel1, i8 20512 ret i8 %sel2513}514 515define <2 x i8> @test_implied_true_vec(<2 x i8> %x) {516; CHECK-LABEL: @test_implied_true_vec(517; CHECK-NEXT: [[CMP2:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer518; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i8> zeroinitializer, <2 x i8> splat (i8 20)519; CHECK-NEXT: ret <2 x i8> [[SEL2]]520;521 %cmp1 = icmp slt <2 x i8> %x, <i8 10, i8 10>522 %cmp2 = icmp slt <2 x i8> %x, zeroinitializer523 %sel1 = select <2 x i1> %cmp1, <2 x i8> zeroinitializer, <2 x i8> <i8 5, i8 5>524 %sel2 = select <2 x i1> %cmp2, <2 x i8> %sel1, <2 x i8> <i8 20, i8 20>525 ret <2 x i8> %sel2526}527 528define i8 @test_implied_true_falseval(i8 %x) {529; CHECK-LABEL: @test_implied_true_falseval(530; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[X:%.*]], 0531; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 20, i8 0532; CHECK-NEXT: ret i8 [[SEL2]]533;534 %cmp1 = icmp slt i8 %x, 10535 %cmp2 = icmp sgt i8 %x, 0536 %sel1 = select i1 %cmp1, i8 0, i8 5537 %sel2 = select i1 %cmp2, i8 20, i8 %sel1538 ret i8 %sel2539}540 541define i8 @test_implied_false(i8 %x) {542; CHECK-LABEL: @test_implied_false(543; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X:%.*]], 0544; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 5, i8 20545; CHECK-NEXT: ret i8 [[SEL2]]546;547 %cmp1 = icmp sgt i8 %x, 10548 %cmp2 = icmp slt i8 %x, 0549 %sel1 = select i1 %cmp1, i8 0, i8 5550 %sel2 = select i1 %cmp2, i8 %sel1, i8 20551 ret i8 %sel2552}553 554; Negative tests555 556define i8 @test_imply_fail(i8 %x) {557; CHECK-LABEL: @test_imply_fail(558; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[X:%.*]], -10559; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X]], 0560; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i8 0, i8 5561; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 [[SEL1]], i8 20562; CHECK-NEXT: ret i8 [[SEL2]]563;564 %cmp1 = icmp slt i8 %x, -10565 %cmp2 = icmp slt i8 %x, 0566 %sel1 = select i1 %cmp1, i8 0, i8 5567 %sel2 = select i1 %cmp2, i8 %sel1, i8 20568 ret i8 %sel2569}570 571define <2 x i8> @test_imply_type_mismatch(<2 x i8> %x, i8 %y) {572; CHECK-LABEL: @test_imply_type_mismatch(573; CHECK-NEXT: [[CMP1:%.*]] = icmp slt <2 x i8> [[X:%.*]], splat (i8 10)574; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0575; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i8> zeroinitializer, <2 x i8> splat (i8 5)576; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], <2 x i8> [[SEL1]], <2 x i8> splat (i8 20)577; CHECK-NEXT: ret <2 x i8> [[SEL2]]578;579 %cmp1 = icmp slt <2 x i8> %x, <i8 10, i8 10>580 %cmp2 = icmp slt i8 %y, 0581 %sel1 = select <2 x i1> %cmp1, <2 x i8> zeroinitializer, <2 x i8> <i8 5, i8 5>582 %sel2 = select i1 %cmp2, <2 x i8> %sel1, <2 x i8> <i8 20, i8 20>583 ret <2 x i8> %sel2584}585 586define <4 x i1> @test_dont_crash(i1 %cond, <4 x i1> %a, <4 x i1> %b) {587; CHECK-LABEL: @test_dont_crash(588; CHECK-NEXT: entry:589; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <4 x i1> [[A:%.*]], <4 x i1> zeroinitializer590; CHECK-NEXT: [[AND:%.*]] = and <4 x i1> [[SEL]], [[B:%.*]]591; CHECK-NEXT: ret <4 x i1> [[AND]]592;593entry:594 %sel = select i1 %cond, <4 x i1> %a, <4 x i1> zeroinitializer595 %and = and <4 x i1> %sel, %b596 ret <4 x i1> %and597}598