1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare i1 @gen() 5 6declare void @use(i8) 7declare void @use1(i1) 8declare void @use2(<2 x i1>) 9 10define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) { 11; CHECK-LABEL: @foo( 12; CHECK-NEXT: [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 13; CHECK-NEXT: [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] 14; CHECK-NEXT: ret i32 [[J]] 15; 16 %e = icmp slt i32 %a, %b 17 %f = sext i1 %e to i32 18 %g = and i32 %c, %f 19 %h = xor i32 %f, -1 20 %i = and i32 %d, %h 21 %j = or i32 %g, %i 22 ret i32 %j 23} 24 25define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) { 26; CHECK-LABEL: @bar( 27; CHECK-NEXT: [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 28; CHECK-NEXT: [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] 29; CHECK-NEXT: ret i32 [[J]] 30; 31 %e = icmp slt i32 %a, %b 32 %f = sext i1 %e to i32 33 %g = and i32 %c, %f 34 %h = xor i32 %f, -1 35 %i = and i32 %d, %h 36 %j = or i32 %i, %g 37 ret i32 %j 38} 39 40define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) { 41; CHECK-LABEL: @goo( 42; CHECK-NEXT: [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 43; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] 44; CHECK-NEXT: ret i32 [[T3]] 45; 46 %t0 = icmp slt i32 %a, %b 47 %iftmp.0.0 = select i1 %t0, i32 -1, i32 0 48 %t1 = and i32 %iftmp.0.0, %c 49 %not = xor i32 %iftmp.0.0, -1 50 %t2 = and i32 %not, %d 51 %t3 = or i32 %t1, %t2 52 ret i32 %t3 53} 54 55define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) { 56; CHECK-LABEL: @poo( 57; CHECK-NEXT: [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 58; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] 59; CHECK-NEXT: ret i32 [[T3]] 60; 61 %t0 = icmp slt i32 %a, %b 62 %iftmp.0.0 = select i1 %t0, i32 -1, i32 0 63 %t1 = and i32 %iftmp.0.0, %c 64 %iftmp = select i1 %t0, i32 0, i32 -1 65 %t2 = and i32 %iftmp, %d 66 %t3 = or i32 %t1, %t2 67 ret i32 %t3 68} 69 70; PR32791 - https://bugs.llvm.org//show_bug.cgi?id=32791 71; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this. 72 73define i32 @fold_inverted_icmp_preds(i32 %a, i32 %b, i32 %c, i32 %d) { 74; CHECK-LABEL: @fold_inverted_icmp_preds( 75; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 76; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0 77; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]] 78; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]] 79; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]] 80; CHECK-NEXT: ret i32 [[OR]] 81; 82 %cmp1 = icmp slt i32 %a, %b 83 %sel1 = select i1 %cmp1, i32 %c, i32 0 84 %cmp2 = icmp sge i32 %a, %b 85 %sel2 = select i1 %cmp2, i32 %d, i32 0 86 %or = or i32 %sel1, %sel2 87 ret i32 %or 88} 89 90; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this. 91 92define i32 @fold_inverted_icmp_preds_reverse(i32 %a, i32 %b, i32 %c, i32 %d) { 93; CHECK-LABEL: @fold_inverted_icmp_preds_reverse( 94; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 95; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]] 96; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]] 97; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 0 98; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]] 99; CHECK-NEXT: ret i32 [[OR]] 100; 101 %cmp1 = icmp slt i32 %a, %b 102 %sel1 = select i1 %cmp1, i32 0, i32 %c 103 %cmp2 = icmp sge i32 %a, %b 104 %sel2 = select i1 %cmp2, i32 0, i32 %d 105 %or = or i32 %sel1, %sel2 106 ret i32 %or 107} 108 109; TODO: Should fcmp have the same sort of predicate canonicalization as icmp? 110 111define i32 @fold_inverted_fcmp_preds(float %a, float %b, i32 %c, i32 %d) { 112; CHECK-LABEL: @fold_inverted_fcmp_preds( 113; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]] 114; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0 115; CHECK-NEXT: [[CMP2:%.*]] = fcmp uge float [[A]], [[B]] 116; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0 117; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]] 118; CHECK-NEXT: ret i32 [[OR]] 119; 120 %cmp1 = fcmp olt float %a, %b 121 %sel1 = select i1 %cmp1, i32 %c, i32 0 122 %cmp2 = fcmp uge float %a, %b 123 %sel2 = select i1 %cmp2, i32 %d, i32 0 124 %or = or i32 %sel1, %sel2 125 ret i32 %or 126} 127 128; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this. 129 130define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) { 131; CHECK-LABEL: @fold_inverted_icmp_vector_preds( 132; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]] 133; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]] 134; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]] 135; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer 136; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]] 137; CHECK-NEXT: ret <2 x i32> [[OR]] 138; 139 %cmp1 = icmp ne <2 x i32> %a, %b 140 %sel1 = select <2 x i1> %cmp1, <2 x i32> %c, <2 x i32> <i32 0, i32 0> 141 %cmp2 = icmp eq <2 x i32> %a, %b 142 %sel2 = select <2 x i1> %cmp2, <2 x i32> %d, <2 x i32> <i32 0, i32 0> 143 %or = or <2 x i32> %sel1, %sel2 144 ret <2 x i32> %or 145} 146 147define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) { 148; CHECK-LABEL: @par( 149; CHECK-NEXT: [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 150; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]] 151; CHECK-NEXT: ret i32 [[T3]] 152; 153 %t0 = icmp slt i32 %a, %b 154 %iftmp.1.0 = select i1 %t0, i32 -1, i32 0 155 %t1 = and i32 %iftmp.1.0, %c 156 %not = xor i32 %iftmp.1.0, -1 157 %t2 = and i32 %not, %d 158 %t3 = or i32 %t1, %t2 159 ret i32 %t3 160} 161 162; In the following tests (8 commutation variants), verify that a bitcast doesn't get 163; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly 164; other vector code because of canonicalization to i64 elements for vectors. 165 166; The fptosi instructions are included to avoid commutation canonicalization based on 167; operator weight. Using another cast operator ensures that both operands of all logic 168; ops are equally weighted, and this ensures that we're testing all commutation 169; possibilities. 170 171define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 172; CHECK-LABEL: @bitcast_select_swap0( 173; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 174; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 175; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 176; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 177; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 178; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 179; CHECK-NEXT: ret <2 x i64> [[OR]] 180; 181 %sia = fptosi <2 x double> %a to <2 x i64> 182 %sib = fptosi <2 x double> %b to <2 x i64> 183 %sext = sext <4 x i1> %cmp to <4 x i32> 184 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 185 %and1 = and <2 x i64> %bc1, %sia 186 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 187 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 188 %and2 = and <2 x i64> %bc2, %sib 189 %or = or <2 x i64> %and1, %and2 190 ret <2 x i64> %or 191} 192 193define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 194; CHECK-LABEL: @bitcast_select_swap1( 195; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 196; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 197; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 198; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 199; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 200; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 201; CHECK-NEXT: ret <2 x i64> [[OR]] 202; 203 %sia = fptosi <2 x double> %a to <2 x i64> 204 %sib = fptosi <2 x double> %b to <2 x i64> 205 %sext = sext <4 x i1> %cmp to <4 x i32> 206 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 207 %and1 = and <2 x i64> %bc1, %sia 208 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 209 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 210 %and2 = and <2 x i64> %bc2, %sib 211 %or = or <2 x i64> %and2, %and1 212 ret <2 x i64> %or 213} 214 215define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 216; CHECK-LABEL: @bitcast_select_swap2( 217; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 218; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 219; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 220; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 221; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 222; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 223; CHECK-NEXT: ret <2 x i64> [[OR]] 224; 225 %sia = fptosi <2 x double> %a to <2 x i64> 226 %sib = fptosi <2 x double> %b to <2 x i64> 227 %sext = sext <4 x i1> %cmp to <4 x i32> 228 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 229 %and1 = and <2 x i64> %bc1, %sia 230 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 231 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 232 %and2 = and <2 x i64> %sib, %bc2 233 %or = or <2 x i64> %and1, %and2 234 ret <2 x i64> %or 235} 236 237define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 238; CHECK-LABEL: @bitcast_select_swap3( 239; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 240; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 241; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 242; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 243; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 244; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 245; CHECK-NEXT: ret <2 x i64> [[OR]] 246; 247 %sia = fptosi <2 x double> %a to <2 x i64> 248 %sib = fptosi <2 x double> %b to <2 x i64> 249 %sext = sext <4 x i1> %cmp to <4 x i32> 250 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 251 %and1 = and <2 x i64> %bc1, %sia 252 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 253 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 254 %and2 = and <2 x i64> %sib, %bc2 255 %or = or <2 x i64> %and2, %and1 256 ret <2 x i64> %or 257} 258 259define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 260; CHECK-LABEL: @bitcast_select_swap4( 261; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 262; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 263; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 264; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 265; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 266; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 267; CHECK-NEXT: ret <2 x i64> [[OR]] 268; 269 %sia = fptosi <2 x double> %a to <2 x i64> 270 %sib = fptosi <2 x double> %b to <2 x i64> 271 %sext = sext <4 x i1> %cmp to <4 x i32> 272 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 273 %and1 = and <2 x i64> %sia, %bc1 274 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 275 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 276 %and2 = and <2 x i64> %bc2, %sib 277 %or = or <2 x i64> %and1, %and2 278 ret <2 x i64> %or 279} 280 281define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 282; CHECK-LABEL: @bitcast_select_swap5( 283; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 284; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 285; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 286; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 287; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 288; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 289; CHECK-NEXT: ret <2 x i64> [[OR]] 290; 291 %sia = fptosi <2 x double> %a to <2 x i64> 292 %sib = fptosi <2 x double> %b to <2 x i64> 293 %sext = sext <4 x i1> %cmp to <4 x i32> 294 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 295 %and1 = and <2 x i64> %sia, %bc1 296 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 297 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 298 %and2 = and <2 x i64> %bc2, %sib 299 %or = or <2 x i64> %and2, %and1 300 ret <2 x i64> %or 301} 302 303define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 304; CHECK-LABEL: @bitcast_select_swap6( 305; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 306; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 307; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 308; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 309; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 310; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 311; CHECK-NEXT: ret <2 x i64> [[OR]] 312; 313 %sia = fptosi <2 x double> %a to <2 x i64> 314 %sib = fptosi <2 x double> %b to <2 x i64> 315 %sext = sext <4 x i1> %cmp to <4 x i32> 316 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 317 %and1 = and <2 x i64> %sia, %bc1 318 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 319 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 320 %and2 = and <2 x i64> %sib, %bc2 321 %or = or <2 x i64> %and1, %and2 322 ret <2 x i64> %or 323} 324 325define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 326; CHECK-LABEL: @bitcast_select_swap7( 327; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 328; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 329; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 330; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 331; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 332; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 333; CHECK-NEXT: ret <2 x i64> [[OR]] 334; 335 %sia = fptosi <2 x double> %a to <2 x i64> 336 %sib = fptosi <2 x double> %b to <2 x i64> 337 %sext = sext <4 x i1> %cmp to <4 x i32> 338 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 339 %and1 = and <2 x i64> %sia, %bc1 340 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 341 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 342 %and2 = and <2 x i64> %sib, %bc2 343 %or = or <2 x i64> %and2, %and1 344 ret <2 x i64> %or 345} 346 347define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) { 348; CHECK-LABEL: @bitcast_select_multi_uses( 349; CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i1> [[CMP:%.*]] to <4 x i32> 350; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64> 351; CHECK-NEXT: [[AND1:%.*]] = and <2 x i64> [[A:%.*]], [[BC1]] 352; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64> 353; CHECK-NEXT: [[BC2:%.*]] = xor <2 x i64> [[TMP1]], splat (i64 -1) 354; CHECK-NEXT: [[AND2:%.*]] = and <2 x i64> [[B:%.*]], [[BC2]] 355; CHECK-NEXT: [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]] 356; CHECK-NEXT: [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]] 357; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]] 358; CHECK-NEXT: ret <2 x i64> [[SUB]] 359; 360 %sext = sext <4 x i1> %cmp to <4 x i32> 361 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 362 %and1 = and <2 x i64> %a, %bc1 363 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 364 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 365 %and2 = and <2 x i64> %b, %bc2 366 %or = or <2 x i64> %and2, %and1 367 %add = add <2 x i64> %and2, %bc2 368 %sub = sub <2 x i64> %or, %add 369 ret <2 x i64> %sub 370} 371 372define i1 @bools(i1 %a, i1 %b, i1 %c) { 373; CHECK-LABEL: @bools( 374; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 375; CHECK-NEXT: ret i1 [[OR]] 376; 377 %not = xor i1 %c, -1 378 %and1 = and i1 %not, %a 379 %and2 = and i1 %c, %b 380 %or = or i1 %and1, %and2 381 ret i1 %or 382} 383 384define i1 @bools_logical(i1 %a, i1 %b, i1 %c) { 385; CHECK-LABEL: @bools_logical( 386; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 387; CHECK-NEXT: ret i1 [[OR]] 388; 389 %not = xor i1 %c, -1 390 %and1 = select i1 %not, i1 %a, i1 false 391 %and2 = select i1 %c, i1 %b, i1 false 392 %or = select i1 %and1, i1 true, i1 %and2 393 ret i1 %or 394} 395 396; Form a select if we know we can replace 2 simple logic ops. 397 398define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) { 399; CHECK-LABEL: @bools_multi_uses1( 400; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true 401; CHECK-NEXT: [[AND1:%.*]] = and i1 [[A:%.*]], [[NOT]] 402; CHECK-NEXT: [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]] 403; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OR]], [[AND1]] 404; CHECK-NEXT: ret i1 [[XOR]] 405; 406 %not = xor i1 %c, -1 407 %and1 = and i1 %not, %a 408 %and2 = and i1 %c, %b 409 %or = or i1 %and1, %and2 410 %xor = xor i1 %or, %and1 411 ret i1 %xor 412} 413 414define i1 @bools_multi_uses1_logical(i1 %a, i1 %b, i1 %c) { 415; CHECK-LABEL: @bools_multi_uses1_logical( 416; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true 417; CHECK-NEXT: [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false 418; CHECK-NEXT: [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]] 419; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OR]], [[AND1]] 420; CHECK-NEXT: ret i1 [[XOR]] 421; 422 %not = xor i1 %c, -1 423 %and1 = select i1 %not, i1 %a, i1 false 424 %and2 = select i1 %c, i1 %b, i1 false 425 %or = select i1 %and1, i1 true, i1 %and2 426 %xor = xor i1 %or, %and1 427 ret i1 %xor 428} 429 430; Don't replace a cheap logic op with a potentially expensive select 431; unless we can also eliminate one of the other original ops. 432 433define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) { 434; CHECK-LABEL: @bools_multi_uses2( 435; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 436; CHECK-NEXT: ret i1 [[OR]] 437; 438 %not = xor i1 %c, -1 439 %and1 = and i1 %not, %a 440 %and2 = and i1 %c, %b 441 %or = or i1 %and1, %and2 442 %add = add i1 %and1, %and2 443 %and3 = and i1 %or, %add 444 ret i1 %and3 445} 446 447define i1 @bools_multi_uses2_logical(i1 %a, i1 %b, i1 %c) { 448; CHECK-LABEL: @bools_multi_uses2_logical( 449; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true 450; CHECK-NEXT: [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false 451; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false 452; CHECK-NEXT: [[OR:%.*]] = select i1 [[C]], i1 [[B]], i1 [[A]] 453; CHECK-NEXT: [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]] 454; CHECK-NEXT: [[AND3:%.*]] = select i1 [[OR]], i1 [[ADD]], i1 false 455; CHECK-NEXT: ret i1 [[AND3]] 456; 457 %not = xor i1 %c, -1 458 %and1 = select i1 %not, i1 %a, i1 false 459 %and2 = select i1 %c, i1 %b, i1 false 460 %or = select i1 %and1, i1 true, i1 %and2 461 %add = add i1 %and1, %and2 462 %and3 = select i1 %or, i1 %add, i1 false 463 ret i1 %and3 464} 465 466define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) { 467; CHECK-LABEL: @vec_of_bools( 468; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[B:%.*]], <4 x i1> [[A:%.*]] 469; CHECK-NEXT: ret <4 x i1> [[OR]] 470; 471 %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true> 472 %and1 = and <4 x i1> %not, %a 473 %and2 = and <4 x i1> %b, %c 474 %or = or <4 x i1> %and2, %and1 475 ret <4 x i1> %or 476} 477 478define <vscale x 1 x i1> @vec_of_bools_scalable(<vscale x 1 x i1> %a, <vscale x 1 x i1> %c, <vscale x 1 x i1> %d) { 479; CHECK-LABEL: @vec_of_bools_scalable( 480; CHECK-NEXT: [[R:%.*]] = select <vscale x 1 x i1> [[A:%.*]], <vscale x 1 x i1> [[C:%.*]], <vscale x 1 x i1> [[D:%.*]] 481; CHECK-NEXT: ret <vscale x 1 x i1> [[R]] 482; 483 %b = xor <vscale x 1 x i1> %a, splat (i1 true) 484 %t11 = and <vscale x 1 x i1> %a, %c 485 %t12 = and <vscale x 1 x i1> %b, %d 486 %r = or <vscale x 1 x i1> %t11, %t12 487 ret <vscale x 1 x i1> %r 488} 489 490define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) { 491; CHECK-LABEL: @vec_of_casted_bools( 492; CHECK-NEXT: [[TMP1:%.*]] = bitcast i4 [[B:%.*]] to <4 x i1> 493; CHECK-NEXT: [[TMP2:%.*]] = bitcast i4 [[A:%.*]] to <4 x i1> 494; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[TMP1]], <4 x i1> [[TMP2]] 495; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i1> [[TMP3]] to i4 496; CHECK-NEXT: ret i4 [[OR]] 497; 498 %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true> 499 %bc1 = bitcast <4 x i1> %not to i4 500 %bc2 = bitcast <4 x i1> %c to i4 501 %and1 = and i4 %a, %bc1 502 %and2 = and i4 %bc2, %b 503 %or = or i4 %and1, %and2 504 ret i4 %or 505} 506 507define <vscale x 1 x i64> @vec_of_casted_bools_scalable(<vscale x 1 x i64> %a, <vscale x 1 x i64> %b, <vscale x 8 x i1> %cond) { 508; CHECK-LABEL: @vec_of_casted_bools_scalable( 509; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 1 x i64> [[A:%.*]] to <vscale x 8 x i8> 510; CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 1 x i64> [[B:%.*]] to <vscale x 8 x i8> 511; CHECK-NEXT: [[TMP3:%.*]] = select <vscale x 8 x i1> [[COND:%.*]], <vscale x 8 x i8> [[TMP1]], <vscale x 8 x i8> [[TMP2]] 512; CHECK-NEXT: [[OR:%.*]] = bitcast <vscale x 8 x i8> [[TMP3]] to <vscale x 1 x i64> 513; CHECK-NEXT: ret <vscale x 1 x i64> [[OR]] 514; 515 %scond = sext <vscale x 8 x i1> %cond to <vscale x 8 x i8> 516 %notcond = xor <vscale x 8 x i1> %cond, splat (i1 true) 517 %snotcond = sext <vscale x 8 x i1> %notcond to <vscale x 8 x i8> 518 %bc1 = bitcast <vscale x 8 x i8> %scond to <vscale x 1 x i64> 519 %bc2 = bitcast <vscale x 8 x i8> %snotcond to <vscale x 1 x i64> 520 %and1 = and <vscale x 1 x i64> %a, %bc1 521 %and2 = and <vscale x 1 x i64> %bc2, %b 522 %or = or <vscale x 1 x i64> %and1, %and2 523 ret <vscale x 1 x i64> %or 524} 525 526; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle. 527 528define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) { 529; CHECK-LABEL: @vec_sel_consts( 530; CHECK-NEXT: [[OR:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3> 531; CHECK-NEXT: ret <4 x i32> [[OR]] 532; 533 %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1> 534 %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0> 535 %or = or <4 x i32> %and1, %and2 536 ret <4 x i32> %or 537} 538 539define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) { 540; CHECK-LABEL: @vec_sel_consts_weird( 541; CHECK-NEXT: [[OR:%.*]] = shufflevector <3 x i129> [[A:%.*]], <3 x i129> [[B:%.*]], <3 x i32> <i32 0, i32 4, i32 2> 542; CHECK-NEXT: ret <3 x i129> [[OR]] 543; 544 %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1> 545 %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0> 546 %or = or <3 x i129> %and2, %and1 547 ret <3 x i129> %or 548} 549 550; The mask elements must be inverted for this to be a select. 551 552define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) { 553; CHECK-LABEL: @vec_not_sel_consts( 554; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 0, i32 0, i32 0> 555; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 -1> 556; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]] 557; CHECK-NEXT: ret <4 x i32> [[OR]] 558; 559 %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0> 560 %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1> 561 %or = or <4 x i32> %and1, %and2 562 ret <4 x i32> %or 563} 564 565define <4 x i32> @vec_not_sel_consts_undef_elts(<4 x i32> %a, <4 x i32> %b) { 566; CHECK-LABEL: @vec_not_sel_consts_undef_elts( 567; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 undef, i32 0, i32 0> 568; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 undef> 569; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]] 570; CHECK-NEXT: ret <4 x i32> [[OR]] 571; 572 %and1 = and <4 x i32> %a, <i32 -1, i32 undef, i32 0, i32 0> 573 %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 undef> 574 %or = or <4 x i32> %and1, %and2 575 ret <4 x i32> %or 576} 577 578; The inverted constants may be operands of xor instructions. 579 580define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { 581; CHECK-LABEL: @vec_sel_xor( 582; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 false, i1 true, i1 true, i1 true> 583; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 584; CHECK-NEXT: ret <4 x i32> [[OR]] 585; 586 %mask = sext <4 x i1> %c to <4 x i32> 587 %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0> 588 %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1> 589 %and1 = and <4 x i32> %not_mask_flip1, %a 590 %and2 = and <4 x i32> %mask_flip1, %b 591 %or = or <4 x i32> %and1, %and2 592 ret <4 x i32> %or 593} 594 595; Allow the transform even if the mask values have multiple uses because 596; there's still a net reduction of instructions from removing the and/and/or. 597 598define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { 599; CHECK-LABEL: @vec_sel_xor_multi_use( 600; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 true, i1 false, i1 false, i1 false> 601; CHECK-NEXT: [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32> 602; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i1> [[C]], <i1 false, i1 true, i1 true, i1 true> 603; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 604; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[OR]], [[MASK_FLIP1]] 605; CHECK-NEXT: ret <4 x i32> [[ADD]] 606; 607 %mask = sext <4 x i1> %c to <4 x i32> 608 %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0> 609 %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1> 610 %and1 = and <4 x i32> %not_mask_flip1, %a 611 %and2 = and <4 x i32> %mask_flip1, %b 612 %or = or <4 x i32> %and1, %and2 613 %add = add <4 x i32> %or, %mask_flip1 614 ret <4 x i32> %add 615} 616 617; The 'ashr' guarantees that we have a bitmask, so this is select with truncated condition. 618 619define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) { 620; CHECK-LABEL: @allSignBits( 621; CHECK-NEXT: [[ISNEG1:%.*]] = icmp slt i32 [[COND:%.*]], 0 622; CHECK-NEXT: [[A1:%.*]] = select i1 [[ISNEG1]], i32 [[TVAL:%.*]], i32 0 623; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[COND]], 0 624; CHECK-NEXT: [[A2:%.*]] = select i1 [[ISNEG]], i32 0, i32 [[FVAL:%.*]] 625; CHECK-NEXT: [[SEL:%.*]] = or i32 [[A1]], [[A2]] 626; CHECK-NEXT: ret i32 [[SEL]] 627; 628 %bitmask = ashr i32 %cond, 31 629 %not_bitmask = xor i32 %bitmask, -1 630 %a1 = and i32 %tval, %bitmask 631 %a2 = and i32 %not_bitmask, %fval 632 %sel = or i32 %a1, %a2 633 ret i32 %sel 634} 635 636define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) { 637; CHECK-LABEL: @allSignBits_vec( 638; CHECK-NEXT: [[ISNEG1:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer 639; CHECK-NEXT: [[A1:%.*]] = select <4 x i1> [[ISNEG1]], <4 x i8> [[TVAL:%.*]], <4 x i8> zeroinitializer 640; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt <4 x i8> [[COND]], zeroinitializer 641; CHECK-NEXT: [[A2:%.*]] = select <4 x i1> [[ISNEG]], <4 x i8> zeroinitializer, <4 x i8> [[FVAL:%.*]] 642; CHECK-NEXT: [[SEL:%.*]] = or <4 x i8> [[A2]], [[A1]] 643; CHECK-NEXT: ret <4 x i8> [[SEL]] 644; 645 %bitmask = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7> 646 %not_bitmask = xor <4 x i8> %bitmask, <i8 -1, i8 -1, i8 -1, i8 -1> 647 %a1 = and <4 x i8> %tval, %bitmask 648 %a2 = and <4 x i8> %fval, %not_bitmask 649 %sel = or <4 x i8> %a2, %a1 650 ret <4 x i8> %sel 651} 652 653; Negative test - make sure that bitcasts from FP do not cause a crash. 654 655define <2 x i64> @fp_bitcast(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 656; CHECK-LABEL: @fp_bitcast( 657; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64> 658; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64> 659; CHECK-NEXT: [[BC1:%.*]] = bitcast <2 x double> [[A]] to <2 x i64> 660; CHECK-NEXT: [[AND1:%.*]] = and <2 x i64> [[SIA]], [[BC1]] 661; CHECK-NEXT: [[BC2:%.*]] = bitcast <2 x double> [[B]] to <2 x i64> 662; CHECK-NEXT: [[AND2:%.*]] = and <2 x i64> [[SIB]], [[BC2]] 663; CHECK-NEXT: [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]] 664; CHECK-NEXT: ret <2 x i64> [[OR]] 665; 666 %sia = fptosi <2 x double> %a to <2 x i64> 667 %sib = fptosi <2 x double> %b to <2 x i64> 668 %bc1 = bitcast <2 x double> %a to <2 x i64> 669 %and1 = and <2 x i64> %sia, %bc1 670 %bc2 = bitcast <2 x double> %b to <2 x i64> 671 %and2 = and <2 x i64> %sib, %bc2 672 %or = or <2 x i64> %and2, %and1 673 ret <2 x i64> %or 674} 675 676define <4 x i32> @computesignbits_through_shuffles(<4 x float> %x, <4 x float> %y, <4 x float> %z) { 677; CHECK-LABEL: @computesignbits_through_shuffles( 678; CHECK-NEXT: [[CMP:%.*]] = fcmp ole <4 x float> [[X:%.*]], [[Y:%.*]] 679; CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32> 680; CHECK-NEXT: [[S1:%.*]] = shufflevector <4 x i32> [[SEXT]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 681; CHECK-NEXT: [[S2:%.*]] = shufflevector <4 x i32> [[SEXT]], <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3> 682; CHECK-NEXT: [[SHUF_OR1:%.*]] = or <4 x i32> [[S1]], [[S2]] 683; CHECK-NEXT: [[S3:%.*]] = shufflevector <4 x i32> [[SHUF_OR1]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 684; CHECK-NEXT: [[S4:%.*]] = shufflevector <4 x i32> [[SHUF_OR1]], <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3> 685; CHECK-NEXT: [[SHUF_OR2:%.*]] = or <4 x i32> [[S3]], [[S4]] 686; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw <4 x i32> [[SHUF_OR2]] to <4 x i1> 687; CHECK-NEXT: [[SEL_V:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[Z:%.*]], <4 x float> [[X]] 688; CHECK-NEXT: [[SEL:%.*]] = bitcast <4 x float> [[SEL_V]] to <4 x i32> 689; CHECK-NEXT: ret <4 x i32> [[SEL]] 690; 691 %cmp = fcmp ole <4 x float> %x, %y 692 %sext = sext <4 x i1> %cmp to <4 x i32> 693 %s1 = shufflevector <4 x i32> %sext, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 694 %s2 = shufflevector <4 x i32> %sext, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3> 695 %shuf_or1 = or <4 x i32> %s1, %s2 696 %s3 = shufflevector <4 x i32> %shuf_or1, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 697 %s4 = shufflevector <4 x i32> %shuf_or1, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3> 698 %shuf_or2 = or <4 x i32> %s3, %s4 699 %not_or2 = xor <4 x i32> %shuf_or2, <i32 -1, i32 -1, i32 -1, i32 -1> 700 %xbc = bitcast <4 x float> %x to <4 x i32> 701 %zbc = bitcast <4 x float> %z to <4 x i32> 702 %and1 = and <4 x i32> %not_or2, %xbc 703 %and2 = and <4 x i32> %shuf_or2, %zbc 704 %sel = or <4 x i32> %and1, %and2 705 ret <4 x i32> %sel 706} 707 708define <4 x i32> @computesignbits_through_two_input_shuffle(<4 x i32> %x, <4 x i32> %y, <4 x i1> %cond1, <4 x i1> %cond2) { 709; CHECK-LABEL: @computesignbits_through_two_input_shuffle( 710; CHECK-NEXT: [[COND:%.*]] = shufflevector <4 x i1> [[COND1:%.*]], <4 x i1> [[COND2:%.*]], <4 x i32> <i32 0, i32 2, i32 4, i32 6> 711; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[COND]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]] 712; CHECK-NEXT: ret <4 x i32> [[SEL]] 713; 714 %sext1 = sext <4 x i1> %cond1 to <4 x i32> 715 %sext2 = sext <4 x i1> %cond2 to <4 x i32> 716 %cond = shufflevector <4 x i32> %sext1, <4 x i32> %sext2, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 717 %notcond = xor <4 x i32> %cond, <i32 -1, i32 -1, i32 -1, i32 -1> 718 %and1 = and <4 x i32> %notcond, %x 719 %and2 = and <4 x i32> %cond, %y 720 %sel = or <4 x i32> %and1, %and2 721 ret <4 x i32> %sel 722} 723 724; Bitcast of condition from narrow source element type can be converted to select. 725 726define <2 x i64> @bitcast_vec_cond(<16 x i1> %cond, <2 x i64> %c, <2 x i64> %d) { 727; CHECK-LABEL: @bitcast_vec_cond( 728; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[D:%.*]] to <16 x i8> 729; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[C:%.*]] to <16 x i8> 730; CHECK-NEXT: [[TMP3:%.*]] = select <16 x i1> [[COND:%.*]], <16 x i8> [[TMP1]], <16 x i8> [[TMP2]] 731; CHECK-NEXT: [[R:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x i64> 732; CHECK-NEXT: ret <2 x i64> [[R]] 733; 734 %s = sext <16 x i1> %cond to <16 x i8> 735 %t9 = bitcast <16 x i8> %s to <2 x i64> 736 %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1> 737 %t11 = and <2 x i64> %nott9, %c 738 %t12 = and <2 x i64> %t9, %d 739 %r = or <2 x i64> %t11, %t12 740 ret <2 x i64> %r 741} 742 743define <vscale x 2 x i64> @bitcast_vec_cond_scalable(<vscale x 16 x i1> %cond, <vscale x 2 x i64> %c, <vscale x 2 x i64> %d) { 744; CHECK-LABEL: @bitcast_vec_cond_scalable( 745; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 2 x i64> [[D:%.*]] to <vscale x 16 x i8> 746; CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 2 x i64> [[C:%.*]] to <vscale x 16 x i8> 747; CHECK-NEXT: [[TMP3:%.*]] = select <vscale x 16 x i1> [[COND:%.*]], <vscale x 16 x i8> [[TMP1]], <vscale x 16 x i8> [[TMP2]] 748; CHECK-NEXT: [[R:%.*]] = bitcast <vscale x 16 x i8> [[TMP3]] to <vscale x 2 x i64> 749; CHECK-NEXT: ret <vscale x 2 x i64> [[R]] 750; 751 %s = sext <vscale x 16 x i1> %cond to <vscale x 16 x i8> 752 %t9 = bitcast <vscale x 16 x i8> %s to <vscale x 2 x i64> 753 %nott9 = xor <vscale x 2 x i64> %t9, splat (i64 -1) 754 %t11 = and <vscale x 2 x i64> %nott9, %c 755 %t12 = and <vscale x 2 x i64> %t9, %d 756 %r = or <vscale x 2 x i64> %t11, %t12 757 ret <vscale x 2 x i64> %r 758} 759 760; Negative test - bitcast of condition from wide source element type cannot be converted to select. 761 762define <8 x i3> @bitcast_vec_cond_commute1(<3 x i1> noundef %cond, <8 x i3> %pc, <8 x i3> %d) { 763; CHECK-LABEL: @bitcast_vec_cond_commute1( 764; CHECK-NEXT: [[C:%.*]] = mul <8 x i3> [[PC:%.*]], [[PC]] 765; CHECK-NEXT: [[S:%.*]] = sext <3 x i1> [[COND:%.*]] to <3 x i8> 766; CHECK-NEXT: [[T9:%.*]] = bitcast <3 x i8> [[S]] to <8 x i3> 767; CHECK-NEXT: [[NOTT9:%.*]] = xor <8 x i3> [[T9]], splat (i3 -1) 768; CHECK-NEXT: [[T11:%.*]] = and <8 x i3> [[C]], [[NOTT9]] 769; CHECK-NEXT: [[T12:%.*]] = and <8 x i3> [[D:%.*]], [[T9]] 770; CHECK-NEXT: [[R:%.*]] = or disjoint <8 x i3> [[T11]], [[T12]] 771; CHECK-NEXT: ret <8 x i3> [[R]] 772; 773 %c = mul <8 x i3> %pc, %pc ; thwart complexity-based canonicalization 774 %s = sext <3 x i1> %cond to <3 x i8> 775 %t9 = bitcast <3 x i8> %s to <8 x i3> 776 %nott9 = xor <8 x i3> %t9, <i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1, i3 -1> 777 %t11 = and <8 x i3> %c, %nott9 778 %t12 = and <8 x i3> %t9, %d 779 %r = or <8 x i3> %t11, %t12 780 ret <8 x i3> %r 781} 782 783define <2 x i16> @bitcast_vec_cond_commute2(<4 x i1> %cond, <2 x i16> %pc, <2 x i16> %pd) { 784; CHECK-LABEL: @bitcast_vec_cond_commute2( 785; CHECK-NEXT: [[C:%.*]] = mul <2 x i16> [[PC:%.*]], [[PC]] 786; CHECK-NEXT: [[D:%.*]] = mul <2 x i16> [[PD:%.*]], [[PD]] 787; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[D]] to <4 x i8> 788; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[C]] to <4 x i8> 789; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[COND:%.*]], <4 x i8> [[TMP1]], <4 x i8> [[TMP2]] 790; CHECK-NEXT: [[R:%.*]] = bitcast <4 x i8> [[TMP3]] to <2 x i16> 791; CHECK-NEXT: ret <2 x i16> [[R]] 792; 793 %c = mul <2 x i16> %pc, %pc ; thwart complexity-based canonicalization 794 %d = mul <2 x i16> %pd, %pd ; thwart complexity-based canonicalization 795 %s = sext <4 x i1> %cond to <4 x i8> 796 %t9 = bitcast <4 x i8> %s to <2 x i16> 797 %nott9 = xor <2 x i16> %t9, <i16 -1, i16 -1> 798 %t11 = and <2 x i16> %c, %nott9 799 %t12 = and <2 x i16> %d, %t9 800 %r = or <2 x i16> %t11, %t12 801 ret <2 x i16> %r 802} 803 804; Condition doesn't have to be a bool vec - just all signbits. 805 806define <2 x i16> @bitcast_vec_cond_commute3(<4 x i8> %cond, <2 x i16> %pc, <2 x i16> %pd) { 807; CHECK-LABEL: @bitcast_vec_cond_commute3( 808; CHECK-NEXT: [[C:%.*]] = mul <2 x i16> [[PC:%.*]], [[PC]] 809; CHECK-NEXT: [[D:%.*]] = mul <2 x i16> [[PD:%.*]], [[PD]] 810; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[D]] to <4 x i8> 811; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[C]] to <4 x i8> 812; CHECK-NEXT: [[DOTNOT2:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer 813; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[DOTNOT2]], <4 x i8> [[TMP1]], <4 x i8> [[TMP2]] 814; CHECK-NEXT: [[R:%.*]] = bitcast <4 x i8> [[TMP3]] to <2 x i16> 815; CHECK-NEXT: ret <2 x i16> [[R]] 816; 817 %c = mul <2 x i16> %pc, %pc ; thwart complexity-based canonicalization 818 %d = mul <2 x i16> %pd, %pd ; thwart complexity-based canonicalization 819 %s = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7> 820 %t9 = bitcast <4 x i8> %s to <2 x i16> 821 %nott9 = xor <2 x i16> %t9, <i16 -1, i16 -1> 822 %t11 = and <2 x i16> %c, %nott9 823 %t12 = and <2 x i16> %d, %t9 824 %r = or <2 x i16> %t11, %t12 825 ret <2 x i16> %r 826} 827 828; Don't crash on invalid type for compute signbits. 829 830define <2 x i64> @bitcast_fp_vec_cond(<2 x double> noundef %s, <2 x i64> %c, <2 x i64> %d) { 831; CHECK-LABEL: @bitcast_fp_vec_cond( 832; CHECK-NEXT: [[T9:%.*]] = bitcast <2 x double> [[S:%.*]] to <2 x i64> 833; CHECK-NEXT: [[NOTT9:%.*]] = xor <2 x i64> [[T9]], splat (i64 -1) 834; CHECK-NEXT: [[T11:%.*]] = and <2 x i64> [[C:%.*]], [[NOTT9]] 835; CHECK-NEXT: [[T12:%.*]] = and <2 x i64> [[D:%.*]], [[T9]] 836; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]] 837; CHECK-NEXT: ret <2 x i64> [[R]] 838; 839 %t9 = bitcast <2 x double> %s to <2 x i64> 840 %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1> 841 %t11 = and <2 x i64> %nott9, %c 842 %t12 = and <2 x i64> %t9, %d 843 %r = or <2 x i64> %t11, %t12 844 ret <2 x i64> %r 845} 846 847; Wider source type would be ok except poison could leak across elements. 848 849define <2 x i64> @bitcast_int_vec_cond(i1 noundef %b, <2 x i64> %c, <2 x i64> %d) { 850; CHECK-LABEL: @bitcast_int_vec_cond( 851; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i128 852; CHECK-NEXT: [[T9:%.*]] = bitcast i128 [[S]] to <2 x i64> 853; CHECK-NEXT: [[NOTT9:%.*]] = xor <2 x i64> [[T9]], splat (i64 -1) 854; CHECK-NEXT: [[T11:%.*]] = and <2 x i64> [[C:%.*]], [[NOTT9]] 855; CHECK-NEXT: [[T12:%.*]] = and <2 x i64> [[D:%.*]], [[T9]] 856; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i64> [[T11]], [[T12]] 857; CHECK-NEXT: ret <2 x i64> [[R]] 858; 859 %s = sext i1 %b to i128 860 %t9 = bitcast i128 %s to <2 x i64> 861 %nott9 = xor <2 x i64> %t9, <i64 -1, i64 -1> 862 %t11 = and <2 x i64> %nott9, %c 863 %t12 = and <2 x i64> %t9, %d 864 %r = or <2 x i64> %t11, %t12 865 ret <2 x i64> %r 866} 867 868; Converting integer logic ops to vector select is allowed. 869 870define i64 @bitcast_int_scalar_cond(<2 x i1> %b, i64 %c, i64 %d) { 871; CHECK-LABEL: @bitcast_int_scalar_cond( 872; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[D:%.*]] to <2 x i32> 873; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64 [[C:%.*]] to <2 x i32> 874; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[B:%.*]], <2 x i32> [[TMP1]], <2 x i32> [[TMP2]] 875; CHECK-NEXT: [[R:%.*]] = bitcast <2 x i32> [[TMP3]] to i64 876; CHECK-NEXT: ret i64 [[R]] 877; 878 %s = sext <2 x i1> %b to <2 x i32> 879 %t9 = bitcast <2 x i32> %s to i64 880 %nott9 = xor i64 %t9, -1 881 %t11 = and i64 %nott9, %c 882 %t12 = and i64 %t9, %d 883 %r = or i64 %t11, %t12 884 ret i64 %r 885} 886 887; Peek through bitcasts and sexts to find negated bool condition. 888 889define <1 x i6> @bitcast_sext_cond(<2 x i1> %cmp, <1 x i6> %a, <1 x i6> %b) { 890; CHECK-LABEL: @bitcast_sext_cond( 891; CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x i6> [[A:%.*]] to <2 x i3> 892; CHECK-NEXT: [[TMP2:%.*]] = bitcast <1 x i6> [[B:%.*]] to <2 x i3> 893; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i3> [[TMP1]], <2 x i3> [[TMP2]] 894; CHECK-NEXT: [[OR:%.*]] = bitcast <2 x i3> [[TMP3]] to <1 x i6> 895; CHECK-NEXT: ret <1 x i6> [[OR]] 896; 897 %sext = sext <2 x i1> %cmp to <2 x i3> 898 %bc1 = bitcast <2 x i3> %sext to <1 x i6> 899 %neg = xor <2 x i1> %cmp, <i1 -1, i1 -1> 900 %sext2 = sext <2 x i1> %neg to <2 x i3> 901 %bc2 = bitcast <2 x i3> %sext2 to <1 x i6> 902 %and1 = and <1 x i6> %bc1, %a 903 %and2 = and <1 x i6> %bc2, %b 904 %or = or <1 x i6> %and1, %and2 905 ret <1 x i6> %or 906} 907 908; Extra uses may prevent other transforms from creating the canonical patterns. 909 910define i8 @sext_cond_extra_uses(i1 %cmp, i8 %a, i8 %b) { 911; CHECK-LABEL: @sext_cond_extra_uses( 912; CHECK-NEXT: [[NEG:%.*]] = xor i1 [[CMP:%.*]], true 913; CHECK-NEXT: [[SEXT1:%.*]] = sext i1 [[CMP]] to i8 914; CHECK-NEXT: call void @use(i8 [[SEXT1]]) 915; CHECK-NEXT: [[SEXT2:%.*]] = sext i1 [[NEG]] to i8 916; CHECK-NEXT: call void @use(i8 [[SEXT2]]) 917; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i8 [[A:%.*]], i8 [[B:%.*]] 918; CHECK-NEXT: ret i8 [[OR]] 919; 920 %neg = xor i1 %cmp, -1 921 %sext1 = sext i1 %cmp to i8 922 call void @use(i8 %sext1) 923 %sext2 = sext i1 %neg to i8 924 call void @use(i8 %sext2) 925 %and1 = and i8 %sext1, %a 926 %and2 = and i8 %sext2, %b 927 %or = or i8 %and1, %and2 928 ret i8 %or 929} 930 931define i1 @xor_commute0(i1 %x, i1 %y) { 932; CHECK-LABEL: @xor_commute0( 933; CHECK-NEXT: [[AND2:%.*]] = xor i1 [[X:%.*]], [[Y:%.*]] 934; CHECK-NEXT: ret i1 [[AND2]] 935; 936 %and = select i1 %x, i1 %y, i1 false 937 %or = select i1 %x, i1 true, i1 %y 938 %nand = xor i1 %and, true 939 %and2 = select i1 %nand, i1 %or, i1 false 940 ret i1 %and2 941} 942 943define i1 @xor_commute1(i1 %x, i1 %y) { 944; CHECK-LABEL: @xor_commute1( 945; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false 946; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true 947; CHECK-NEXT: call void @use1(i1 [[NAND]]) 948; CHECK-NEXT: [[AND2:%.*]] = xor i1 [[X]], [[Y]] 949; CHECK-NEXT: ret i1 [[AND2]] 950; 951 %and = select i1 %x, i1 %y, i1 false 952 %or = select i1 %y, i1 true, i1 %x 953 %nand = xor i1 %and, true 954 call void @use1(i1 %nand) 955 %and2 = select i1 %nand, i1 %or, i1 false 956 ret i1 %and2 957} 958 959define i1 @xor_commute2(i1 %x, i1 %y) { 960; CHECK-LABEL: @xor_commute2( 961; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false 962; CHECK-NEXT: call void @use1(i1 [[AND]]) 963; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]] 964; CHECK-NEXT: call void @use1(i1 [[OR]]) 965; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true 966; CHECK-NEXT: call void @use1(i1 [[NAND]]) 967; CHECK-NEXT: [[AND2:%.*]] = xor i1 [[X]], [[Y]] 968; CHECK-NEXT: ret i1 [[AND2]] 969; 970 %and = select i1 %x, i1 %y, i1 false 971 call void @use1(i1 %and) 972 %or = select i1 %x, i1 true, i1 %y 973 call void @use1(i1 %or) 974 %nand = xor i1 %and, true 975 call void @use1(i1 %nand) 976 %and2 = select i1 %or, i1 %nand, i1 false 977 ret i1 %and2 978} 979 980define <2 x i1> @xor_commute3(<2 x i1> %x, <2 x i1> %y) { 981; CHECK-LABEL: @xor_commute3( 982; CHECK-NEXT: [[AND2:%.*]] = xor <2 x i1> [[X:%.*]], [[Y:%.*]] 983; CHECK-NEXT: ret <2 x i1> [[AND2]] 984; 985 %and = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 false, i1 false> 986 %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 987 %nand = xor <2 x i1> %and, <i1 true, i1 true> 988 %and2 = select <2 x i1> %or, <2 x i1> %nand, <2 x i1> <i1 false, i1 false> 989 ret <2 x i1> %and2 990} 991 992define i1 @not_d_bools_commute00(i1 %c, i1 %x, i1 %y) { 993; CHECK-LABEL: @not_d_bools_commute00( 994; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[Y:%.*]], true 995; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]] 996; CHECK-NEXT: ret i1 [[R]] 997; 998 %y_c = or i1 %c, %y 999 %and2 = xor i1 %y_c, true 1000 %and1 = and i1 %c, %x 1001 %r = or i1 %and1, %and2 1002 ret i1 %r 1003} 1004 1005define i1 @not_d_bools_commute01(i1 %c, i1 %x, i1 %y) { 1006; CHECK-LABEL: @not_d_bools_commute01( 1007; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[Y:%.*]], true 1008; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]] 1009; CHECK-NEXT: ret i1 [[R]] 1010; 1011 %y_c = or i1 %y, %c 1012 %and2 = xor i1 %y_c, true 1013 %and1 = and i1 %c, %x 1014 %r = or i1 %and1, %and2 1015 ret i1 %r 1016} 1017 1018define i1 @not_d_bools_commute10(i1 %c, i1 %x, i1 %y) { 1019; CHECK-LABEL: @not_d_bools_commute10( 1020; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[Y:%.*]], true 1021; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]] 1022; CHECK-NEXT: ret i1 [[R]] 1023; 1024 %y_c = or i1 %c, %y 1025 %and2 = xor i1 %y_c, true 1026 %and1 = and i1 %x, %c 1027 %r = or i1 %and1, %and2 1028 ret i1 %r 1029} 1030 1031define i1 @not_d_bools_commute11(i1 %c, i1 %x, i1 %y) { 1032; CHECK-LABEL: @not_d_bools_commute11( 1033; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[Y:%.*]], true 1034; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 [[TMP1]] 1035; CHECK-NEXT: ret i1 [[R]] 1036; 1037 %y_c = or i1 %y, %c 1038 %and2 = xor i1 %y_c, true 1039 %and1 = and i1 %x, %c 1040 %r = or i1 %and1, %and2 1041 ret i1 %r 1042} 1043 1044define <2 x i1> @not_d_bools_vector(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) { 1045; CHECK-LABEL: @not_d_bools_vector( 1046; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[Y:%.*]], splat (i1 true) 1047; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> [[TMP1]] 1048; CHECK-NEXT: ret <2 x i1> [[R]] 1049; 1050 %y_c = or <2 x i1> %y, %c 1051 %and2 = xor <2 x i1> %y_c, <i1 true, i1 true> 1052 %and1 = and <2 x i1> %x, %c 1053 %r = or <2 x i1> %and1, %and2 1054 ret <2 x i1> %r 1055} 1056 1057define <2 x i1> @not_d_bools_vector_poison(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y) { 1058; CHECK-LABEL: @not_d_bools_vector_poison( 1059; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[Y:%.*]], splat (i1 true) 1060; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> [[TMP1]] 1061; CHECK-NEXT: ret <2 x i1> [[R]] 1062; 1063 %y_c = or <2 x i1> %y, %c 1064 %and2 = xor <2 x i1> %y_c, <i1 poison, i1 true> 1065 %and1 = and <2 x i1> %x, %c 1066 %r = or <2 x i1> %and1, %and2 1067 ret <2 x i1> %r 1068} 1069 1070define i32 @not_d_allSignBits(i32 %cond, i32 %tval, i32 %fval) { 1071; CHECK-LABEL: @not_d_allSignBits( 1072; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[FVAL:%.*]], -1 1073; CHECK-NEXT: [[DOTNOT2:%.*]] = icmp slt i32 [[COND:%.*]], 0 1074; CHECK-NEXT: [[SEL:%.*]] = select i1 [[DOTNOT2]], i32 [[TVAL:%.*]], i32 [[TMP1]] 1075; CHECK-NEXT: ret i32 [[SEL]] 1076; 1077 %bitmask = ashr i32 %cond, 31 1078 %a1 = and i32 %tval, %bitmask 1079 %or = or i32 %bitmask, %fval 1080 %a2 = xor i32 %or, -1 1081 %sel = or i32 %a1, %a2 1082 ret i32 %sel 1083} 1084 1085define i1 @not_d_bools_use2(i1 %c, i1 %x, i1 %y) { 1086; CHECK-LABEL: @not_d_bools_use2( 1087; CHECK-NEXT: [[Y_C:%.*]] = or i1 [[C:%.*]], [[Y:%.*]] 1088; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C]], [[X:%.*]] 1089; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[Y]], true 1090; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i1 [[X]], i1 [[TMP1]] 1091; CHECK-NEXT: call void @use1(i1 [[AND1]]) 1092; CHECK-NEXT: call void @use1(i1 [[Y_C]]) 1093; CHECK-NEXT: ret i1 [[R]] 1094; 1095 %y_c = or i1 %c, %y 1096 %and2 = xor i1 %y_c, true 1097 %and1 = and i1 %c, %x 1098 %r = or i1 %and1, %and2 1099 call void @use1(i1 %and1) 1100 call void @use1(i1 %y_c) 1101 ret i1 %r 1102} 1103 1104; negative test: both op is not one-use 1105 1106define i1 @not_d_bools_negative_use2(i1 %c, i1 %x, i1 %y) { 1107; CHECK-LABEL: @not_d_bools_negative_use2( 1108; CHECK-NEXT: [[Y_C:%.*]] = or i1 [[C:%.*]], [[Y:%.*]] 1109; CHECK-NEXT: [[AND2:%.*]] = xor i1 [[Y_C]], true 1110; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C]], [[X:%.*]] 1111; CHECK-NEXT: [[R:%.*]] = or i1 [[AND1]], [[AND2]] 1112; CHECK-NEXT: call void @use1(i1 [[AND2]]) 1113; CHECK-NEXT: call void @use1(i1 [[AND1]]) 1114; CHECK-NEXT: ret i1 [[R]] 1115; 1116 %y_c = or i1 %c, %y 1117 %and2 = xor i1 %y_c, true 1118 %and1 = and i1 %c, %x 1119 %r = or i1 %and1, %and2 1120 call void @use1(i1 %and2) 1121 call void @use1(i1 %and1) 1122 ret i1 %r 1123} 1124 1125; A & (~C | B) 1126define i1 @logical_and_or_with_not_op(i1 %a, i1 %b, i1 %c) { 1127; CHECK-LABEL: @logical_and_or_with_not_op( 1128; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true 1129; CHECK-NEXT: [[OR:%.*]] = or i1 [[B:%.*]], [[NOT]] 1130; CHECK-NEXT: [[AND:%.*]] = select i1 [[A:%.*]], i1 [[OR]], i1 false 1131; CHECK-NEXT: ret i1 [[AND]] 1132; 1133 %not = xor i1 %c, true 1134 %or = or i1 %not, %b 1135 %and = select i1 %a, i1 %or, i1 zeroinitializer 1136 ret i1 %and 1137} 1138 1139; As logical_and_or_with_not_op but with C=A 1140; A & (~A | B) --> A & B 1141define i1 @logical_and_or_with_common_not_op_variant1(i1 %a, i1 %b) { 1142; CHECK-LABEL: @logical_and_or_with_common_not_op_variant1( 1143; CHECK-NEXT: [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 1144; CHECK-NEXT: ret i1 [[AND]] 1145; 1146 %not = xor i1 %a, true 1147 %or = or i1 %not, %b 1148 %and = select i1 %a, i1 %or, i1 zeroinitializer 1149 ret i1 %and 1150} 1151 1152; As logical_and_or_with_common_not_op_variant1 but operating on vectors 1153; A & (~A | B) --> A & B 1154define <2 x i1> @logical_and_or_with_common_not_op_variant2(<2 x i1> %a, <2 x i1> %b) { 1155; CHECK-LABEL: @logical_and_or_with_common_not_op_variant2( 1156; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 1157; CHECK-NEXT: ret <2 x i1> [[AND]] 1158; 1159 %not = xor <2 x i1> %a, <i1 true, i1 true> 1160 %or = or <2 x i1> %not, %b 1161 %and = select <2 x i1> %a, <2 x i1> %or, <2 x i1> zeroinitializer 1162 ret <2 x i1> %and 1163} 1164 1165; As logical_and_or_with_common_not_op_variant1 but with "or" implemented as 1166; "select X, true, Y" 1167; A & (~A | B) --> A & B 1168define i1 @logical_and_or_with_common_not_op_variant3(i1 %a, i1 %b) { 1169; CHECK-LABEL: @logical_and_or_with_common_not_op_variant3( 1170; CHECK-NEXT: [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 1171; CHECK-NEXT: ret i1 [[AND]] 1172; 1173 %not = xor i1 %a, true 1174 %or = select i1 %not, i1 true, i1 %b 1175 %and = select i1 %a, i1 %or, i1 zeroinitializer 1176 ret i1 %and 1177} 1178 1179; As logical_and_or_with_common_not_op_variant3 but operating on vectors where 1180; each operand has other uses 1181; A & (~A | B) --> A & B 1182define <2 x i1> @logical_and_or_with_common_not_op_variant4(<2 x i1> %a, <2 x i1> %b) { 1183; CHECK-LABEL: @logical_and_or_with_common_not_op_variant4( 1184; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true) 1185; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[NOT]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]] 1186; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B]], <2 x i1> zeroinitializer 1187; CHECK-NEXT: call void @use2(<2 x i1> [[A]]) 1188; CHECK-NEXT: call void @use2(<2 x i1> [[B]]) 1189; CHECK-NEXT: call void @use2(<2 x i1> [[OR]]) 1190; CHECK-NEXT: ret <2 x i1> [[AND]] 1191; 1192 %not = xor <2 x i1> %a, <i1 true, i1 true> 1193 %or = select <2 x i1> %not, <2 x i1> <i1 true, i1 true>, <2 x i1> %b 1194 %and = select <2 x i1> %a, <2 x i1> %or, <2 x i1> zeroinitializer 1195 call void @use2(<2 x i1> %a) 1196 call void @use2(<2 x i1> %b) 1197 call void @use2(<2 x i1> %or) 1198 ret <2 x i1> %and 1199} 1200 1201; As logical_and_or_with_common_not_op_variant1 but with |'s operands swapped 1202; A & (B | ~A) --> A & B 1203define i1 @logical_and_or_with_common_not_op_variant5(i1 %a) { 1204; CHECK-LABEL: @logical_and_or_with_common_not_op_variant5( 1205; CHECK-NEXT: [[B:%.*]] = call i1 @gen() 1206; CHECK-NEXT: [[AND:%.*]] = select i1 [[A:%.*]], i1 [[B]], i1 false 1207; CHECK-NEXT: ret i1 [[AND]] 1208; 1209 %b = call i1 @gen() 1210 %not = xor i1 %a, true 1211 %or = or i1 %b, %not 1212 %and = select i1 %a, i1 %or, i1 zeroinitializer 1213 ret i1 %and 1214} 1215 1216; A | (~C & B) 1217define i1 @logical_or_and_with_not_op(i1 %a, i1 %b, i1 %c) { 1218; CHECK-LABEL: @logical_or_and_with_not_op( 1219; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[C:%.*]], true 1220; CHECK-NEXT: [[AND:%.*]] = and i1 [[B:%.*]], [[NOT]] 1221; CHECK-NEXT: [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[AND]] 1222; CHECK-NEXT: ret i1 [[OR]] 1223; 1224 %not = xor i1 %c, true 1225 %and = and i1 %not, %b 1226 %or = select i1 %a, i1 true, i1 %and 1227 ret i1 %or 1228} 1229 1230; As logical_or_and_with_not_op but with C=A 1231; A | (~A & B) --> A | B 1232define i1 @logical_or_and_with_common_not_op_variant1(i1 %a, i1 %b) { 1233; CHECK-LABEL: @logical_or_and_with_common_not_op_variant1( 1234; CHECK-NEXT: [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 1235; CHECK-NEXT: ret i1 [[OR]] 1236; 1237 %not = xor i1 %a, true 1238 %and = and i1 %not, %b 1239 %or = select i1 %a, i1 true, i1 %and 1240 ret i1 %or 1241} 1242 1243; As logical_or_and_with_common_not_op_variant1 but operating on vectors 1244; A | (~A & B) --> A | B 1245define <2 x i1> @logical_or_and_with_common_not_op_variant2(<2 x i1> %a, <2 x i1> %b) { 1246; CHECK-LABEL: @logical_or_and_with_common_not_op_variant2( 1247; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]] 1248; CHECK-NEXT: ret <2 x i1> [[OR]] 1249; 1250 %not = xor <2 x i1> %a, <i1 true, i1 true> 1251 %and = and <2 x i1> %not, %b 1252 %or = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %and 1253 ret <2 x i1> %or 1254} 1255 1256; As logical_or_and_with_common_not_op_variant1 but with "and" implemented as 1257; "select X, Y, false" 1258; A | (~A & B) --> A | B 1259define i1 @logical_or_and_with_common_not_op_variant3(i1 %a, i1 %b) { 1260; CHECK-LABEL: @logical_or_and_with_common_not_op_variant3( 1261; CHECK-NEXT: [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 1262; CHECK-NEXT: ret i1 [[OR]] 1263; 1264 %not = xor i1 %a, true 1265 %and = select i1 %not, i1 %b, i1 false 1266 %or = select i1 %a, i1 true, i1 %and 1267 ret i1 %or 1268} 1269 1270; As logical_or_and_with_common_not_op_variant3 but operating on vectors where 1271; each operand has other uses 1272; A | (~A & B) --> A | B 1273define <2 x i1> @logical_or_and_with_common_not_op_variant4(<2 x i1> %a, <2 x i1> %b) { 1274; CHECK-LABEL: @logical_or_and_with_common_not_op_variant4( 1275; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true) 1276; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 1277; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[A]], <2 x i1> splat (i1 true), <2 x i1> [[B]] 1278; CHECK-NEXT: call void @use2(<2 x i1> [[A]]) 1279; CHECK-NEXT: call void @use2(<2 x i1> [[B]]) 1280; CHECK-NEXT: call void @use2(<2 x i1> [[AND]]) 1281; CHECK-NEXT: ret <2 x i1> [[OR]] 1282; 1283 %not = xor <2 x i1> %a, <i1 true, i1 true> 1284 %and = select <2 x i1> %not, <2 x i1> %b, <2 x i1> zeroinitializer 1285 %or = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %and 1286 call void @use2(<2 x i1> %a) 1287 call void @use2(<2 x i1> %b) 1288 call void @use2(<2 x i1> %and) 1289 ret <2 x i1> %or 1290} 1291 1292; As logical_or_and_with_common_not_op_variant1 but with &'s operands swapped 1293; A | (B & ~A) --> A | B 1294define i1 @logical_or_and_with_common_not_op_variant5(i1 %a) { 1295; CHECK-LABEL: @logical_or_and_with_common_not_op_variant5( 1296; CHECK-NEXT: [[B:%.*]] = call i1 @gen() 1297; CHECK-NEXT: [[OR:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B]] 1298; CHECK-NEXT: ret i1 [[OR]] 1299; 1300 %b = call i1 @gen() 1301 %not = xor i1 %a, true 1302 %and = and i1 %b, %not 1303 %or = select i1 %a, i1 true, i1 %and 1304 ret i1 %or 1305} 1306 1307define i1 @reduce_logical_and1(i1 %a, i32 %b, i32 %c) { 1308; CHECK-LABEL: @reduce_logical_and1( 1309; CHECK-NEXT: bb: 1310; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1311; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1312; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CMP1]], [[CMP]] 1313; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP0]], i1 false 1314; CHECK-NEXT: ret i1 [[AND2]] 1315; 1316bb: 1317 %cmp = icmp slt i32 %b, 6 1318 %cmp1 = icmp sgt i32 %c, %b 1319 %and1 = select i1 %a, i1 %cmp1, i1 false 1320 %and2 = select i1 %and1, i1 %cmp, i1 false 1321 ret i1 %and2 1322} 1323 1324define i1 @reduce_logical_and2(i1 %a, i1 %b, i1 %c) { 1325; CHECK-LABEL: @reduce_logical_and2( 1326; CHECK-NEXT: bb: 1327; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true 1328; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[B:%.*]], [[TMP0]] 1329; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false 1330; CHECK-NEXT: ret i1 [[AND2]] 1331; 1332bb: 1333 %or = xor i1 %c, %b 1334 %and1 = select i1 %a, i1 %or, i1 false 1335 %and2 = select i1 %and1, i1 %b, i1 false 1336 ret i1 %and2 1337} 1338 1339define i1 @reduce_logical_and3(i1 %a, i32 %b, i32 noundef %c) { 1340; CHECK-LABEL: @reduce_logical_and3( 1341; CHECK-NEXT: bb: 1342; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1343; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1344; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CMP]], [[CMP1]] 1345; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 [[TMP0]], i1 false 1346; CHECK-NEXT: ret i1 [[AND2]] 1347; 1348bb: 1349 %cmp = icmp slt i32 %b, 6 1350 %cmp1 = icmp sgt i32 %c, %b 1351 %and1 = select i1 %a, i1 %cmp, i1 false 1352 %and2 = select i1 %and1, i1 %cmp1, i1 false 1353 ret i1 %and2 1354} 1355 1356define i1 @reduce_logical_or1(i1 %a, i32 %b, i32 %c) { 1357; CHECK-LABEL: @reduce_logical_or1( 1358; CHECK-NEXT: bb: 1359; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1360; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1361; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[CMP1]], [[CMP]] 1362; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]] 1363; CHECK-NEXT: ret i1 [[AND2]] 1364; 1365bb: 1366 %cmp = icmp slt i32 %b, 6 1367 %cmp1 = icmp sgt i32 %c, %b 1368 %and1 = select i1 %a, i1 true, i1 %cmp1 1369 %and2 = select i1 %and1, i1 true, i1 %cmp 1370 ret i1 %and2 1371} 1372 1373define i1 @reduce_logical_or2(i1 %a, i1 %b, i1 %c) { 1374; CHECK-LABEL: @reduce_logical_or2( 1375; CHECK-NEXT: bb: 1376; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[C:%.*]], [[B:%.*]] 1377; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]] 1378; CHECK-NEXT: ret i1 [[AND2]] 1379; 1380bb: 1381 %or = xor i1 %c, %b 1382 %and1 = select i1 %a, i1 true, i1 %or 1383 %and2 = select i1 %and1, i1 true, i1 %b 1384 ret i1 %and2 1385} 1386 1387define i1 @reduce_logical_or3(i1 %a, i32 %b, i32 noundef %c) { 1388; CHECK-LABEL: @reduce_logical_or3( 1389; CHECK-NEXT: bb: 1390; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1391; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1392; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[CMP]], [[CMP1]] 1393; CHECK-NEXT: [[AND2:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP0]] 1394; CHECK-NEXT: ret i1 [[AND2]] 1395; 1396bb: 1397 %cmp = icmp slt i32 %b, 6 1398 %cmp1 = icmp sgt i32 %c, %b 1399 %and1 = select i1 %a, i1 true, i1 %cmp 1400 %and2 = select i1 %and1, i1 true, i1 %cmp1 1401 ret i1 %and2 1402} 1403 1404define i1 @reduce_logical_and_fail1(i1 %a, i32 %b, i32 %c) { 1405; CHECK-LABEL: @reduce_logical_and_fail1( 1406; CHECK-NEXT: bb: 1407; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1408; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1409; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP]], i1 false 1410; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP1]], i1 false 1411; CHECK-NEXT: ret i1 [[AND2]] 1412; 1413bb: 1414 %cmp = icmp slt i32 %b, 6 1415 %cmp1 = icmp sgt i32 %c, %b 1416 %and1 = select i1 %a, i1 %cmp, i1 false 1417 %and2 = select i1 %and1, i1 %cmp1, i1 false 1418 ret i1 %and2 1419} 1420 1421define i1 @reduce_logical_and_fail2(i1 %a, i32 %b, i32 %c) { 1422; CHECK-LABEL: @reduce_logical_and_fail2( 1423; CHECK-NEXT: bb: 1424; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1425; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], 7 1426; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP]], i1 false 1427; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP1]], i1 false 1428; CHECK-NEXT: ret i1 [[AND2]] 1429; 1430bb: 1431 %cmp = icmp slt i32 %b, 6 1432 %cmp1 = icmp sgt i32 %c, 7 1433 %and1 = select i1 %a, i1 %cmp, i1 false 1434 %and2 = select i1 %and1, i1 %cmp1, i1 false 1435 ret i1 %and2 1436} 1437 1438define i1 @reduce_logical_or_fail1(i1 %a, i32 %b, i32 %c) { 1439; CHECK-LABEL: @reduce_logical_or_fail1( 1440; CHECK-NEXT: bb: 1441; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1442; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1443; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[CMP]] 1444; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 [[CMP1]] 1445; CHECK-NEXT: ret i1 [[AND2]] 1446; 1447bb: 1448 %cmp = icmp slt i32 %b, 6 1449 %cmp1 = icmp sgt i32 %c, %b 1450 %and1 = select i1 %a, i1 true, i1 %cmp 1451 %and2 = select i1 %and1, i1 true, i1 %cmp1 1452 ret i1 %and2 1453} 1454 1455define i1 @reduce_logical_or_fail2(i1 %a, i32 %b, i32 %c) { 1456; CHECK-LABEL: @reduce_logical_or_fail2( 1457; CHECK-NEXT: bb: 1458; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1459; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], 7 1460; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[CMP]] 1461; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 [[CMP1]] 1462; CHECK-NEXT: ret i1 [[AND2]] 1463; 1464bb: 1465 %cmp = icmp slt i32 %b, 6 1466 %cmp1 = icmp sgt i32 %c, 7 1467 %and1 = select i1 %a, i1 true, i1 %cmp 1468 %and2 = select i1 %and1, i1 true, i1 %cmp1 1469 ret i1 %and2 1470} 1471 1472define i1 @reduce_logical_and_multiuse(i1 %a, i32 %b, i32 %c) { 1473; CHECK-LABEL: @reduce_logical_and_multiuse( 1474; CHECK-NEXT: bb: 1475; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1476; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1477; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP1]], i1 false 1478; CHECK-NEXT: call void @use1(i1 [[AND1]]) 1479; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[CMP]], i1 false 1480; CHECK-NEXT: ret i1 [[AND2]] 1481; 1482bb: 1483 %cmp = icmp slt i32 %b, 6 1484 %cmp1 = icmp sgt i32 %c, %b 1485 %and1 = select i1 %a, i1 %cmp1, i1 false 1486 call void @use1(i1 %and1) 1487 %and2 = select i1 %and1, i1 %cmp, i1 false 1488 ret i1 %and2 1489} 1490 1491define i1 @reduce_bitwise_and1(i1 %a, i32 %b, i32 %c) { 1492; CHECK-LABEL: @reduce_bitwise_and1( 1493; CHECK-NEXT: bb: 1494; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1495; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1496; CHECK-NEXT: [[AND1:%.*]] = or i1 [[A:%.*]], [[CMP1]] 1497; CHECK-NEXT: [[AND2:%.*]] = and i1 [[AND1]], [[CMP]] 1498; CHECK-NEXT: ret i1 [[AND2]] 1499; 1500bb: 1501 %cmp = icmp slt i32 %b, 6 1502 %cmp1 = icmp sgt i32 %c, %b 1503 %and1 = or i1 %a, %cmp1 1504 %and2 = select i1 %and1, i1 %cmp, i1 false 1505 ret i1 %and2 1506} 1507 1508define i1 @reduce_bitwise_and2(i1 %a, i32 %b, i32 %c) { 1509; CHECK-LABEL: @reduce_bitwise_and2( 1510; CHECK-NEXT: bb: 1511; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B:%.*]], 6 1512; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[C:%.*]], [[B]] 1513; CHECK-NEXT: [[AND1:%.*]] = select i1 [[A:%.*]], i1 [[CMP1]], i1 false 1514; CHECK-NEXT: [[AND2:%.*]] = or i1 [[AND1]], [[CMP]] 1515; CHECK-NEXT: ret i1 [[AND2]] 1516; 1517bb: 1518 %cmp = icmp slt i32 %b, 6 1519 %cmp1 = icmp sgt i32 %c, %b 1520 %and1 = select i1 %a, i1 %cmp1, i1 false 1521 %and2 = or i1 %and1, %cmp 1522 ret i1 %and2 1523} 1524 1525define i1 @test_logical_and_icmp_samesign(i8 %x) { 1526; CHECK-LABEL: @test_logical_and_icmp_samesign( 1527; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 9 1528; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i8 [[X]], 11 1529; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1530; CHECK-NEXT: ret i1 [[AND]] 1531; 1532 %cmp1 = icmp ne i8 %x, 9 1533 %cmp2 = icmp samesign ult i8 %x, 11 1534 %and = select i1 %cmp1, i1 %cmp2, i1 false 1535 ret i1 %and 1536} 1537 1538define i1 @test_logical_or_icmp_samesign(i8 %x) { 1539; CHECK-LABEL: @test_logical_or_icmp_samesign( 1540; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], -9 1541; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i8 [[X]], -11 1542; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 1543; CHECK-NEXT: ret i1 [[OR]] 1544; 1545 %cmp1 = icmp eq i8 %x, -9 1546 %cmp2 = icmp samesign ult i8 %x, -11 1547 %or = select i1 %cmp1, i1 true, i1 %cmp2 1548 ret i1 %or 1549} 1550 1551define i1 @test_double_logical_and_icmp_samesign1(i1 %cond, i32 %y) { 1552; CHECK-LABEL: @test_double_logical_and_icmp_samesign1( 1553; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[Y:%.*]], 4 1554; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[SEL1:%.*]], i1 [[CMP2]], i1 false 1555; CHECK-NEXT: ret i1 [[SEL2]] 1556; 1557 %cmp1 = icmp ne i32 %y, 5 1558 %sel1 = select i1 %cond, i1 %cmp1, i1 false 1559 %cmp2 = icmp samesign ult i32 %y, 4 1560 %sel2 = select i1 %sel1, i1 %cmp2, i1 false 1561 ret i1 %sel2 1562} 1563 1564define i1 @test_double_logical_and_icmp_samesign2(i1 %cond, i32 %y) { 1565; CHECK-LABEL: @test_double_logical_and_icmp_samesign2( 1566; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], -65536 1567; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[TMP1]], 1048576 1568; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[SEL1:%.*]], i1 [[CMP2]], i1 false 1569; CHECK-NEXT: ret i1 [[SEL2]] 1570; 1571 %cmp1 = icmp samesign ugt i32 %y, 65535 1572 %sel1 = select i1 %cond, i1 %cmp1, i1 false 1573 %cmp2 = icmp samesign ult i32 %y, 1114112 1574 %sel2 = select i1 %sel1, i1 %cmp2, i1 false 1575 ret i1 %sel2 1576} 1577 1578define <2 x i1> @test_logical_and_icmp_samesign_vec(<2 x i8> %x) { 1579; CHECK-LABEL: @test_logical_and_icmp_samesign_vec( 1580; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], splat (i8 9) 1581; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], splat (i8 11) 1582; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]] 1583; CHECK-NEXT: ret <2 x i1> [[AND]] 1584; 1585 %cmp1 = icmp ne <2 x i8> %x, splat(i8 9) 1586 %cmp2 = icmp samesign ult <2 x i8> %x, splat(i8 11) 1587 %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer 1588 ret <2 x i1> %and 1589} 1590 1591define <2 x i1> @test_logical_and_icmp_samesign_vec_with_poison_cond(<2 x i8> %x) { 1592; CHECK-LABEL: @test_logical_and_icmp_samesign_vec_with_poison_cond( 1593; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 9, i8 poison> 1594; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], splat (i8 11) 1595; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[CMP1]], [[CMP2]] 1596; CHECK-NEXT: ret <2 x i1> [[AND]] 1597; 1598 %cmp1 = icmp ne <2 x i8> %x, <i8 9, i8 poison> 1599 %cmp2 = icmp samesign ult <2 x i8> %x, splat(i8 11) 1600 %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer 1601 ret <2 x i1> %and 1602} 1603 1604define i1 @test_logical_and_icmp_samesign_do_not_imply(i8 %x) { 1605; CHECK-LABEL: @test_logical_and_icmp_samesign_do_not_imply( 1606; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[X:%.*]], 11 1607; CHECK-NEXT: ret i1 [[AND]] 1608; 1609 %cmp1 = icmp ne i8 %x, -9 1610 %cmp2 = icmp samesign ult i8 %x, 11 1611 %and = select i1 %cmp1, i1 %cmp2, i1 false 1612 ret i1 %and 1613} 1614 1615define i1 @test_logical_and_icmp_no_samesign(i8 %x) { 1616; CHECK-LABEL: @test_logical_and_icmp_no_samesign( 1617; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 9 1618; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[X]], 11 1619; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 1620; CHECK-NEXT: ret i1 [[AND]] 1621; 1622 %cmp1 = icmp ne i8 %x, 9 1623 %cmp2 = icmp ult i8 %x, 11 1624 %and = select i1 %cmp1, i1 %cmp2, i1 false 1625 ret i1 %and 1626} 1627 1628; Negative tests 1629 1630define <2 x i1> @test_logical_and_icmp_samesign_vec_with_poison_tv(<2 x i8> %x) { 1631; CHECK-LABEL: @test_logical_and_icmp_samesign_vec_with_poison_tv( 1632; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], splat (i8 9) 1633; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult <2 x i8> [[X]], <i8 11, i8 poison> 1634; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[CMP1]], <2 x i1> [[CMP2]], <2 x i1> zeroinitializer 1635; CHECK-NEXT: ret <2 x i1> [[AND]] 1636; 1637 %cmp1 = icmp ne <2 x i8> %x, splat(i8 9) 1638 %cmp2 = icmp samesign ult <2 x i8> %x, <i8 11, i8 poison> 1639 %and = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> zeroinitializer 1640 ret <2 x i1> %and 1641} 1642