1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4declare void @use.i1(i1) 5declare void @use.i8(i8) 6 7; Basic test 8 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.cond 16 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 17 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 18 ret i8 %outer.sel 19} 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.cond 27 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 28 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 29 ret i8 %outer.sel 30} 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 false 37; 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 false 43 call void @use.i1(i1 %outer.cond) 44 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 45 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 46 ret i8 %outer.sel 47} 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.cond 57 call void @use.i1(i1 %outer.cond) 58 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 59 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 60 ret i8 %outer.sel 61} 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 false 72 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 73 call void @use.i8(i8 %inner.sel) 74 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 75 ret i8 %outer.sel 76} 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.cond 86 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 87 call void @use.i8(i8 %inner.sel) 88 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 89 ret i8 %outer.sel 90} 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 false 95; 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 false 102 call void @use.i1(i1 %outer.cond) 103 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 104 call void @use.i8(i8 %inner.sel) 105 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 106 ret i8 %outer.sel 107} 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.cond 118 call void @use.i1(i1 %outer.cond) 119 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 120 call void @use.i8(i8 %inner.sel) 121 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 122 ret i8 %outer.sel 123} 124 125; Mismatched 'common' cond 126 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 false 130; 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 false 136 %inner.sel = select i1 %inner.cond.v1, i8 %inner.sel.trueval, i8 %inner.sel.falseval 137 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 138 ret i8 %outer.sel 139} 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.cond 148 %inner.sel = select i1 %inner.cond.v1, i8 %inner.sel.trueval, i8 %inner.sel.falseval 149 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 150 ret i8 %outer.sel 151} 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:%.*]], true 156; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false 157; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true 158; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false 159; 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, -1 163 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 164 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1 165 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false 166 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel 167 ret i1 %outer.sel 168} 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:%.*]], true 172; 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:%.*]], true 174; 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, -1 179 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 180 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1 181 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval 182 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval 183 ret i1 %outer.sel 184} 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:%.*]], true 189; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false 190; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND_V1:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false 191; 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, -1 195 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 196 %inner.sel = select i1 %inner.cond.v1, i1 %inner.sel.falseval, i1 false 197 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel 198 ret i1 %outer.sel 199} 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:%.*]], true 203; 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, -1 209 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 210 %inner.sel = select i1 %inner.cond.v1, i1 true, i1 %inner.sel.trueval 211 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval 212 ret i1 %outer.sel 213} 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 false 218; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND_V1:%.*]], true 219; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false 220; 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.cond 224 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1 225 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false 226 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel 227 ret i1 %outer.sel 228} 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:%.*]], true 233; 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.cond 238 %not.inner.cond.1 = xor i1 %inner.cond.v1, -1 239 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval 240 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval 241 ret i1 %outer.sel 242} 243 244; Not an inversion 245; Based on reproduced from https://reviews.llvm.org/D139275#4001580 246define 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, %c1 255 %outer.cond = and i1 %c2, %c1 256 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 257 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 258 ret i8 %outer.sel 259} 260 261; Tests with intervening inversions 262 263; In %outer.sel, %outer.cond is inverted 264define 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:%.*]], true 267; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false 268; 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.cond 272 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval 273 %not.outer.cond = xor i1 %outer.cond, -1 274 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false 275 ret i1 %outer.sel 276} 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:%.*]], true 280; 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.cond 285 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval 286 %not.outer.cond = xor i1 %outer.cond, -1 287 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel 288 ret i1 %outer.sel 289} 290 291; In %inner.sel, %inner.cond is inverted 292define 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 false 295; 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.cond 299 %not.inner.cond = xor i1 %inner.cond, -1 300 %inner.sel = select i1 %not.inner.cond, i1 %inner.sel.falseval, i1 false 301 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel 302 ret i1 %outer.sel 303} 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.cond 311 %not.inner.cond = xor i1 %inner.cond, -1 312 %inner.sel = select i1 %not.inner.cond, i1 true, i1 %inner.sel.trueval 313 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval 314 ret i1 %outer.sel 315} 316 317; In %outer.cond, %inner.cond is inverted 318define 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, -1 325 %outer.cond = select i1 %not.inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 326 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 327 %outer.sel = select i1 %outer.cond, i8 %outer.sel.trueval, i8 %inner.sel 328 ret i8 %outer.sel 329} 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, -1 337 %outer.cond = select i1 %not.inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 338 %inner.sel = select i1 %inner.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval 339 %outer.sel = select i1 %outer.cond, i8 %inner.sel, i8 %outer.sel.falseval 340 ret i8 %outer.sel 341} 342 343; In %outer.sel, %outer.cond is inverted 344; In %inner.sel, %inner.cond is inverted 345define 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:%.*]], true 348; 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:%.*]], true 351; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_FALSEVAL]], i1 false 352; CHECK-NEXT: [[NOT_INNER_COND1:%.*]] = xor i1 [[INNER_COND]], true 353; 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.cond 357 %not.inner.cond = xor i1 %inner.cond, -1 358 %inner.sel = select i1 %not.inner.cond, i1 true, i1 %inner.sel.falseval 359 %not.outer.cond = xor i1 %outer.cond, -1 360 call void @use.i1(i1 %inner.sel) 361 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false 362 ret i1 %outer.sel 363} 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:%.*]], true 367; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false 368; CHECK-NEXT: call void @use.i1(i1 [[TMP1]]) 369; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true 370; 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]], true 372; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND1]], i1 [[INNER_SEL]], i1 false 373; CHECK-NEXT: ret i1 [[OUTER_SEL]] 374; 375 %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 376 %not.inner.cond = xor i1 %inner.cond, -1 377 %inner.sel = select i1 %not.inner.cond, i1 %inner.sel.trueval, i1 false 378 call void @use.i1(i1 %inner.sel) 379 %not.outer.cond = xor i1 %outer.cond, -1 380 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel 381 ret i1 %outer.sel 382} 383 384; In %outer.sel, %outer.cond is inverted 385; In %outer.cond, %inner.cond is inverted 386define 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:%.*]], true 391; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND_NOT]], i1 [[INNER_SEL_FALSEVAL]], i1 false 392; 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, -1 396 %outer.cond = select i1 %not.inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 397 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval 398 call void @use.i1(i1 %inner.sel) 399 %not.outer.cond = xor i1 %outer.cond, -1 400 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false 401 ret i1 %outer.sel 402} 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:%.*]], true 408; 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, -1 413 %outer.cond = select i1 %not.inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 414 %inner.sel = select i1 %inner.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval 415 call void @use.i1(i1 %inner.sel) 416 %not.outer.cond = xor i1 %outer.cond, -1 417 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel 418 ret i1 %outer.sel 419} 420 421; In %inner.sel, %inner.cond is inverted 422; In %outer.cond, %inner.cond is inverted 423define 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:%.*]], true 426; 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 false 428; CHECK-NEXT: ret i1 [[OUTER_SEL]] 429; 430 %not.inner.cond.0 = xor i1 %inner.cond, -1 431 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 432 %not.inner.cond.1 = xor i1 %inner.cond, -1 433 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false 434 %outer.sel = select i1 %outer.cond, i1 %outer.sel.trueval, i1 %inner.sel 435 ret i1 %outer.sel 436} 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:%.*]], true 440; 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, -1 445 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 446 %not.inner.cond.1 = xor i1 %inner.cond, -1 447 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval 448 %outer.sel = select i1 %outer.cond, i1 %inner.sel, i1 %outer.sel.falseval 449 ret i1 %outer.sel 450} 451 452; In %outer.sel, %outer.cond is inverted 453; In %inner.sel, %inner.cond is inverted 454; In %outer.cond, %inner.cond is inverted 455define 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:%.*]], true 458; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false 459; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]]) 460; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND]], true 461; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false 462; 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]], true 465; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[TMP3]], i1 [[INNER_SEL_FALSEVAL]], i1 false 466; CHECK-NEXT: ret i1 [[OUTER_SEL]] 467; 468 %not.inner.cond.0 = xor i1 %inner.cond, -1 469 %outer.cond = select i1 %not.inner.cond.0, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond 470 call void @use.i1(i1 %outer.cond) 471 %not.inner.cond.1 = xor i1 %inner.cond, -1 472 %inner.sel = select i1 %not.inner.cond.1, i1 %inner.sel.falseval, i1 false 473 call void @use.i1(i1 %inner.sel) 474 %not.outer.cond = xor i1 %outer.cond, -1 475 %outer.sel = select i1 %not.outer.cond, i1 %inner.sel, i1 false 476 ret i1 %outer.sel 477} 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:%.*]], true 481; 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]], true 484; 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 false 487; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 488; 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, -1 492 %outer.cond = select i1 %not.inner.cond.0, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond 493 call void @use.i1(i1 %outer.cond) 494 %not.inner.cond.1 = xor i1 %inner.cond, -1 495 %inner.sel = select i1 %not.inner.cond.1, i1 true, i1 %inner.sel.trueval 496 call void @use.i1(i1 %inner.sel) 497 %not.outer.cond = xor i1 %outer.cond, -1 498 %outer.sel = select i1 %not.outer.cond, i1 true, i1 %inner.sel 499 ret i1 %outer.sel 500} 501 502define i8 @test_implied_true(i8 %x) { 503; CHECK-LABEL: @test_implied_true( 504; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X:%.*]], 0 505; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 0, i8 20 506; CHECK-NEXT: ret i8 [[SEL2]] 507; 508 %cmp1 = icmp slt i8 %x, 10 509 %cmp2 = icmp slt i8 %x, 0 510 %sel1 = select i1 %cmp1, i8 0, i8 5 511 %sel2 = select i1 %cmp2, i8 %sel1, i8 20 512 ret i8 %sel2 513} 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:%.*]], zeroinitializer 518; 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, zeroinitializer 523 %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> %sel2 526} 527 528define i8 @test_implied_true_falseval(i8 %x) { 529; CHECK-LABEL: @test_implied_true_falseval( 530; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[X:%.*]], 0 531; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 20, i8 0 532; CHECK-NEXT: ret i8 [[SEL2]] 533; 534 %cmp1 = icmp slt i8 %x, 10 535 %cmp2 = icmp sgt i8 %x, 0 536 %sel1 = select i1 %cmp1, i8 0, i8 5 537 %sel2 = select i1 %cmp2, i8 20, i8 %sel1 538 ret i8 %sel2 539} 540 541define i8 @test_implied_false(i8 %x) { 542; CHECK-LABEL: @test_implied_false( 543; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X:%.*]], 0 544; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 5, i8 20 545; CHECK-NEXT: ret i8 [[SEL2]] 546; 547 %cmp1 = icmp sgt i8 %x, 10 548 %cmp2 = icmp slt i8 %x, 0 549 %sel1 = select i1 %cmp1, i8 0, i8 5 550 %sel2 = select i1 %cmp2, i8 %sel1, i8 20 551 ret i8 %sel2 552} 553 554; Negative tests 555 556define i8 @test_imply_fail(i8 %x) { 557; CHECK-LABEL: @test_imply_fail( 558; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[X:%.*]], -10 559; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[X]], 0 560; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i8 0, i8 5 561; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i8 [[SEL1]], i8 20 562; CHECK-NEXT: ret i8 [[SEL2]] 563; 564 %cmp1 = icmp slt i8 %x, -10 565 %cmp2 = icmp slt i8 %x, 0 566 %sel1 = select i1 %cmp1, i8 0, i8 5 567 %sel2 = select i1 %cmp2, i8 %sel1, i8 20 568 ret i8 %sel2 569} 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:%.*]], 0 575; 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, 0 581 %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> %sel2 584} 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> zeroinitializer 590; 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> zeroinitializer 595 %and = and <4 x i1> %sel, %b 596 ret <4 x i1> %and 597} 598