1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare void @use(i1) 5declare i1 @gen_i1() 6declare <2 x i1> @gen_v2i1() 7 8; Should not be converted to "and", which has different poison semantics. 9define i1 @logical_and(i1 %a, i1 %b) { 10; CHECK-LABEL: @logical_and( 11; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 12; CHECK-NEXT: ret i1 [[RES]] 13; 14 %res = select i1 %a, i1 %b, i1 false 15 ret i1 %res 16} 17 18; Should not be converted to "or", which has different poison semantics. 19define i1 @logical_or(i1 %a, i1 %b) { 20; CHECK-LABEL: @logical_or( 21; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 22; CHECK-NEXT: ret i1 [[RES]] 23; 24 %res = select i1 %a, i1 true, i1 %b 25 ret i1 %res 26} 27; Canonicalize to logical and form, even if that requires adding a "not". 28define i1 @logical_and_not(i1 %a, i1 %b) { 29; CHECK-LABEL: @logical_and_not( 30; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 31; CHECK-NEXT: [[RES:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false 32; CHECK-NEXT: ret i1 [[RES]] 33; 34 %res = select i1 %a, i1 false, i1 %b 35 ret i1 %res 36} 37 38; Canonicalize to logical or form, even if that requires adding a "not". 39define i1 @logical_or_not(i1 %a, i1 %b) { 40; CHECK-LABEL: @logical_or_not( 41; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 42; CHECK-NEXT: [[RES:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]] 43; CHECK-NEXT: ret i1 [[RES]] 44; 45 %res = select i1 %a, i1 %b, i1 true 46 ret i1 %res 47} 48 49; These are variants where condition or !condition is used to represent true 50; or false in one of the select arms. It should be canonicalized to the 51; constants. 52 53define i1 @logical_and_cond_reuse(i1 %a, i1 %b) { 54; CHECK-LABEL: @logical_and_cond_reuse( 55; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 56; CHECK-NEXT: ret i1 [[RES]] 57; 58 %res = select i1 %a, i1 %b, i1 %a 59 ret i1 %res 60} 61 62define i1 @logical_or_cond_reuse(i1 %a, i1 %b) { 63; CHECK-LABEL: @logical_or_cond_reuse( 64; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 65; CHECK-NEXT: ret i1 [[RES]] 66; 67 %res = select i1 %a, i1 %a, i1 %b 68 ret i1 %res 69} 70 71define i1 @logical_and_not_cond_reuse(i1 %a, i1 %b) { 72; CHECK-LABEL: @logical_and_not_cond_reuse( 73; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 74; CHECK-NEXT: [[RES:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]] 75; CHECK-NEXT: ret i1 [[RES]] 76; 77 %a.not = xor i1 %a, true 78 %res = select i1 %a, i1 %b, i1 %a.not 79 ret i1 %res 80} 81 82define i1 @logical_or_not_cond_reuse(i1 %a, i1 %b) { 83; CHECK-LABEL: @logical_or_not_cond_reuse( 84; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true 85; CHECK-NEXT: [[RES:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false 86; CHECK-NEXT: ret i1 [[RES]] 87; 88 %a.not = xor i1 %a, true 89 %res = select i1 %a, i1 %a.not, i1 %b 90 ret i1 %res 91} 92 93; Safe to convert to or due to poison implication. 94define i1 @logical_or_implies(i32 %x) { 95; CHECK-LABEL: @logical_or_implies( 96; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X:%.*]], 0 97; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X]], 42 98; CHECK-NEXT: [[RES:%.*]] = or i1 [[C1]], [[C2]] 99; CHECK-NEXT: ret i1 [[RES]] 100; 101 %c1 = icmp eq i32 %x, 0 102 %c2 = icmp eq i32 %x, 42 103 %res = select i1 %c1, i1 true, i1 %c2 104 ret i1 %res 105} 106 107; Will fold after conversion to or. 108define i1 @logical_or_implies_folds(i32 %x) { 109; CHECK-LABEL: @logical_or_implies_folds( 110; CHECK-NEXT: ret i1 true 111; 112 %c1 = icmp slt i32 %x, 0 113 %c2 = icmp sge i32 %x, 0 114 %res = select i1 %c1, i1 true, i1 %c2 115 ret i1 %res 116} 117 118; Safe to convert to and due to poison implication. 119define i1 @logical_and_implies(i32 %x) { 120; CHECK-LABEL: @logical_and_implies( 121; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X:%.*]], 0 122; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[X]], 42 123; CHECK-NEXT: [[RES:%.*]] = and i1 [[C1]], [[C2]] 124; CHECK-NEXT: ret i1 [[RES]] 125; 126 %c1 = icmp ne i32 %x, 0 127 %c2 = icmp ne i32 %x, 42 128 %res = select i1 %c1, i1 %c2, i1 false 129 ret i1 %res 130} 131 132; Will fold after conversion to and. 133define i1 @logical_and_implies_folds(i32 %x) { 134; CHECK-LABEL: @logical_and_implies_folds( 135; CHECK-NEXT: [[C1:%.*]] = icmp ugt i32 [[X:%.*]], 42 136; CHECK-NEXT: ret i1 [[C1]] 137; 138 %c1 = icmp ugt i32 %x, 42 139 %c2 = icmp ne i32 %x, 0 140 %res = select i1 %c1, i1 %c2, i1 false 141 ret i1 %res 142} 143 144; Noundef on condition has no effect. 145define i1 @logical_or_noundef_a(i1 noundef %a, i1 %b) { 146; CHECK-LABEL: @logical_or_noundef_a( 147; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 148; CHECK-NEXT: ret i1 [[RES]] 149; 150 %res = select i1 %a, i1 true, i1 %b 151 ret i1 %res 152} 153 154; Noundef on false value allows conversion to or. 155define i1 @logical_or_noundef_b(i1 %a, i1 noundef %b) { 156; CHECK-LABEL: @logical_or_noundef_b( 157; CHECK-NEXT: [[RES:%.*]] = or i1 [[A:%.*]], [[B:%.*]] 158; CHECK-NEXT: ret i1 [[RES]] 159; 160 %res = select i1 %a, i1 true, i1 %b 161 ret i1 %res 162} 163 164; Noundef on condition has no effect. 165define i1 @logical_and_noundef_a(i1 noundef %a, i1 %b) { 166; CHECK-LABEL: @logical_and_noundef_a( 167; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 168; CHECK-NEXT: ret i1 [[RES]] 169; 170 %res = select i1 %a, i1 %b, i1 false 171 ret i1 %res 172} 173 174; Noundef on false value allows conversion to and. 175define i1 @logical_and_noundef_b(i1 %a, i1 noundef %b) { 176; CHECK-LABEL: @logical_and_noundef_b( 177; CHECK-NEXT: [[RES:%.*]] = and i1 [[A:%.*]], [[B:%.*]] 178; CHECK-NEXT: ret i1 [[RES]] 179; 180 %res = select i1 %a, i1 %b, i1 false 181 ret i1 %res 182} 183 184; (!x && !y) || x --> x || !y 185 186define i1 @not_not_true(i1 %x, i1 %y) { 187; CHECK-LABEL: @not_not_true( 188; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 189; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[NOTY]] 190; CHECK-NEXT: ret i1 [[R]] 191; 192 %notx = xor i1 %x, true 193 %noty = xor i1 %y, true 194 %r = select i1 %notx, i1 %noty, i1 true 195 ret i1 %r 196} 197 198; (!x && !y) --> !(x || y) 199 200define i1 @not_not_false(i1 %x, i1 %y) { 201; CHECK-LABEL: @not_not_false( 202; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] 203; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 204; CHECK-NEXT: ret i1 [[R]] 205; 206 %notx = xor i1 %x, true 207 %noty = xor i1 %y, true 208 %r = select i1 %notx, i1 %noty, i1 false 209 ret i1 %r 210} 211 212; (!x || !y) --> !(x && y) 213 214define i1 @not_true_not(i1 %x, i1 %y) { 215; CHECK-LABEL: @not_true_not( 216; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false 217; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 218; CHECK-NEXT: ret i1 [[R]] 219; 220 %notx = xor i1 %x, true 221 %noty = xor i1 %y, true 222 %r = select i1 %notx, i1 true, i1 %noty 223 ret i1 %r 224} 225 226; (!!x && !y) --> x && !y 227 228define i1 @not_false_not(i1 %x, i1 %y) { 229; CHECK-LABEL: @not_false_not( 230; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 231; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false 232; CHECK-NEXT: ret i1 [[R]] 233; 234 %notx = xor i1 %x, true 235 %noty = xor i1 %y, true 236 %r = select i1 %notx, i1 false, i1 %noty 237 ret i1 %r 238} 239 240define i1 @not_not_true_use1(i1 %x, i1 %y) { 241; CHECK-LABEL: @not_not_true_use1( 242; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 243; CHECK-NEXT: call void @use(i1 [[NOTX]]) 244; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 245; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i1 true, i1 [[NOTY]] 246; CHECK-NEXT: ret i1 [[R]] 247; 248 %notx = xor i1 %x, true 249 call void @use(i1 %notx) 250 %noty = xor i1 %y, true 251 %r = select i1 %notx, i1 %noty, i1 true 252 ret i1 %r 253} 254 255define i1 @not_not_false_use1(i1 %x, i1 %y) { 256; CHECK-LABEL: @not_not_false_use1( 257; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 258; CHECK-NEXT: call void @use(i1 [[NOTX]]) 259; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X]], i1 true, i1 [[Y:%.*]] 260; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 261; CHECK-NEXT: ret i1 [[R]] 262; 263 %notx = xor i1 %x, true 264 call void @use(i1 %notx) 265 %noty = xor i1 %y, true 266 %r = select i1 %notx, i1 %noty, i1 false 267 ret i1 %r 268} 269 270define i1 @not_true_not_use1(i1 %x, i1 %y) { 271; CHECK-LABEL: @not_true_not_use1( 272; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 273; CHECK-NEXT: call void @use(i1 [[NOTX]]) 274; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false 275; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 276; CHECK-NEXT: ret i1 [[R]] 277; 278 %notx = xor i1 %x, true 279 call void @use(i1 %notx) 280 %noty = xor i1 %y, true 281 %r = select i1 %notx, i1 true, i1 %noty 282 ret i1 %r 283} 284 285define i1 @not_false_not_use1(i1 %x, i1 %y) { 286; CHECK-LABEL: @not_false_not_use1( 287; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 288; CHECK-NEXT: call void @use(i1 [[NOTX]]) 289; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 290; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i1 [[NOTY]], i1 false 291; CHECK-NEXT: ret i1 [[R]] 292; 293 %notx = xor i1 %x, true 294 call void @use(i1 %notx) 295 %noty = xor i1 %y, true 296 %r = select i1 %notx, i1 false, i1 %noty 297 ret i1 %r 298} 299 300define i1 @not_not_true_use2(i1 %x, i1 %y) { 301; CHECK-LABEL: @not_not_true_use2( 302; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 303; CHECK-NEXT: call void @use(i1 [[NOTY]]) 304; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[NOTY]] 305; CHECK-NEXT: ret i1 [[R]] 306; 307 %notx = xor i1 %x, true 308 %noty = xor i1 %y, true 309 call void @use(i1 %noty) 310 %r = select i1 %notx, i1 %noty, i1 true 311 ret i1 %r 312} 313 314define i1 @not_not_false_use2(i1 %x, i1 %y) { 315; CHECK-LABEL: @not_not_false_use2( 316; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 317; CHECK-NEXT: call void @use(i1 [[NOTY]]) 318; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y]] 319; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 320; CHECK-NEXT: ret i1 [[R]] 321; 322 %notx = xor i1 %x, true 323 %noty = xor i1 %y, true 324 call void @use(i1 %noty) 325 %r = select i1 %notx, i1 %noty, i1 false 326 ret i1 %r 327} 328 329define i1 @not_true_not_use2(i1 %x, i1 %y) { 330; CHECK-LABEL: @not_true_not_use2( 331; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 332; CHECK-NEXT: call void @use(i1 [[NOTY]]) 333; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false 334; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true 335; CHECK-NEXT: ret i1 [[R]] 336; 337 %notx = xor i1 %x, true 338 %noty = xor i1 %y, true 339 call void @use(i1 %noty) 340 %r = select i1 %notx, i1 true, i1 %noty 341 ret i1 %r 342} 343 344define i1 @not_false_not_use2(i1 %x, i1 %y) { 345; CHECK-LABEL: @not_false_not_use2( 346; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 347; CHECK-NEXT: call void @use(i1 [[NOTY]]) 348; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false 349; CHECK-NEXT: ret i1 [[R]] 350; 351 %notx = xor i1 %x, true 352 %noty = xor i1 %y, true 353 call void @use(i1 %noty) 354 %r = select i1 %notx, i1 false, i1 %noty 355 ret i1 %r 356} 357 358define i1 @not_not_true_use3(i1 %x, i1 %y) { 359; CHECK-LABEL: @not_not_true_use3( 360; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 361; CHECK-NEXT: call void @use(i1 [[NOTX]]) 362; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 363; CHECK-NEXT: call void @use(i1 [[NOTY]]) 364; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i1 true, i1 [[NOTY]] 365; CHECK-NEXT: ret i1 [[R]] 366; 367 %notx = xor i1 %x, true 368 call void @use(i1 %notx) 369 %noty = xor i1 %y, true 370 call void @use(i1 %noty) 371 %r = select i1 %notx, i1 %noty, i1 true 372 ret i1 %r 373} 374 375define i1 @not_not_false_use3(i1 %x, i1 %y) { 376; CHECK-LABEL: @not_not_false_use3( 377; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 378; CHECK-NEXT: call void @use(i1 [[NOTX]]) 379; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 380; CHECK-NEXT: call void @use(i1 [[NOTY]]) 381; CHECK-NEXT: [[R:%.*]] = select i1 [[NOTX]], i1 [[NOTY]], i1 false 382; CHECK-NEXT: ret i1 [[R]] 383; 384 %notx = xor i1 %x, true 385 call void @use(i1 %notx) 386 %noty = xor i1 %y, true 387 call void @use(i1 %noty) 388 %r = select i1 %notx, i1 %noty, i1 false 389 ret i1 %r 390} 391 392define i1 @not_true_not_use3(i1 %x, i1 %y) { 393; CHECK-LABEL: @not_true_not_use3( 394; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 395; CHECK-NEXT: call void @use(i1 [[NOTX]]) 396; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 397; CHECK-NEXT: call void @use(i1 [[NOTY]]) 398; CHECK-NEXT: [[R:%.*]] = select i1 [[NOTX]], i1 true, i1 [[NOTY]] 399; CHECK-NEXT: ret i1 [[R]] 400; 401 %notx = xor i1 %x, true 402 call void @use(i1 %notx) 403 %noty = xor i1 %y, true 404 call void @use(i1 %noty) 405 %r = select i1 %notx, i1 true, i1 %noty 406 ret i1 %r 407} 408 409define i1 @not_false_not_use3(i1 %x, i1 %y) { 410; CHECK-LABEL: @not_false_not_use3( 411; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true 412; CHECK-NEXT: call void @use(i1 [[NOTX]]) 413; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true 414; CHECK-NEXT: call void @use(i1 [[NOTY]]) 415; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i1 [[NOTY]], i1 false 416; CHECK-NEXT: ret i1 [[R]] 417; 418 %notx = xor i1 %x, true 419 call void @use(i1 %notx) 420 %noty = xor i1 %y, true 421 call void @use(i1 %noty) 422 %r = select i1 %notx, i1 false, i1 %noty 423 ret i1 %r 424} 425 426; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35399 427 428@g1 = external global i16 429@g2 = external global i16 430 431define i1 @demorgan_select_infloop1(i1 %L) { 432; CHECK-LABEL: @demorgan_select_infloop1( 433; CHECK-NEXT: [[NOT_L:%.*]] = xor i1 [[L:%.*]], true 434; CHECK-NEXT: ret i1 [[NOT_L]] 435; 436 %not.L = xor i1 %L, true 437 %cmp = icmp eq ptr getelementptr inbounds (i16, ptr @g2, i64 1), @g1 438 %add = add i1 %cmp, %cmp 439 %xor = xor i1 %add, true 440 %C15 = select i1 %not.L, i1 %xor, i1 false 441 ret i1 %C15 442} 443 444 445define i1 @demorgan_select_infloop2(i1 %L) { 446; CHECK-LABEL: @demorgan_select_infloop2( 447; CHECK-NEXT: [[NOT_L:%.*]] = xor i1 [[L:%.*]], true 448; CHECK-NEXT: [[CMP2:%.*]] = icmp ne ptr getelementptr inbounds nuw (i8, ptr @g2, i64 2), @g1 449; CHECK-NEXT: [[C15:%.*]] = select i1 [[NOT_L]], i1 [[CMP2]], i1 false 450; CHECK-NEXT: ret i1 [[C15]] 451; 452 %not.L = xor i1 %L, true 453 %cmp1 = icmp eq ptr getelementptr inbounds (i16, ptr @g1, i64 1), @g1 454 %cmp2 = icmp eq ptr getelementptr inbounds (i16, ptr @g2, i64 1), @g1 455 %add = add i1 %cmp1, %cmp2 456 %xor = xor i1 %add, true 457 %C15 = select i1 %not.L, i1 %xor, i1 false 458 ret i1 %C15 459} 460 461define i1 @and_or1(i1 %a, i1 %b, i1 %c) { 462; CHECK-LABEL: @and_or1( 463; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] 464; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false 465; CHECK-NEXT: ret i1 [[R]] 466; 467 %nota = xor i1 %a, true 468 %cond = or i1 %nota, %c 469 %r = select i1 %cond, i1 %a, i1 %b 470 ret i1 %r 471} 472 473define i1 @and_or2(i1 %a, i1 %b, i1 %c) { 474; CHECK-LABEL: @and_or2( 475; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] 476; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false 477; CHECK-NEXT: ret i1 [[R]] 478; 479 %notc = xor i1 %c, true 480 %cond = and i1 %notc, %b 481 %r = select i1 %cond, i1 %a, i1 %b 482 ret i1 %r 483} 484 485define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) { 486; CHECK-LABEL: @and_or1_commuted( 487; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]] 488; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false 489; CHECK-NEXT: ret i1 [[R]] 490; 491 %nota = xor i1 %a, true 492 %cond = or i1 %c, %nota 493 %r = select i1 %cond, i1 %a, i1 %b 494 ret i1 %r 495} 496 497define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) { 498; CHECK-LABEL: @and_or2_commuted( 499; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] 500; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false 501; CHECK-NEXT: ret i1 [[R]] 502; 503 %notc = xor i1 %c, true 504 %cond = and i1 %b, %notc 505 %r = select i1 %cond, i1 %a, i1 %b 506 ret i1 %r 507} 508 509define i1 @and_or1_multiuse(i1 %a, i1 %b, i1 %c) { 510; CHECK-LABEL: @and_or1_multiuse( 511; CHECK-NEXT: [[NOTA:%.*]] = xor i1 [[A:%.*]], true 512; CHECK-NEXT: [[COND:%.*]] = or i1 [[C:%.*]], [[NOTA]] 513; CHECK-NEXT: call void @use(i1 [[COND]]) 514; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]] 515; CHECK-NEXT: ret i1 [[R]] 516; 517 %nota = xor i1 %a, true 518 %cond = or i1 %nota, %c 519 call void @use(i1 %cond) 520 %r = select i1 %cond, i1 %a, i1 %b 521 ret i1 %r 522} 523 524define i1 @and_or2_multiuse(i1 %a, i1 %b, i1 %c) { 525; CHECK-LABEL: @and_or2_multiuse( 526; CHECK-NEXT: [[NOTC:%.*]] = xor i1 [[C:%.*]], true 527; CHECK-NEXT: [[COND:%.*]] = and i1 [[B:%.*]], [[NOTC]] 528; CHECK-NEXT: call void @use(i1 [[COND]]) 529; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]] 530; CHECK-NEXT: ret i1 [[R]] 531; 532 %notc = xor i1 %c, true 533 %cond = and i1 %notc, %b 534 call void @use(i1 %cond) 535 %r = select i1 %cond, i1 %a, i1 %b 536 ret i1 %r 537} 538 539define <2 x i1> @and_or1_vec(<2 x i1> %a, <2 x i1> %b) { 540; CHECK-LABEL: @and_or1_vec( 541; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 542; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]] 543; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer 544; CHECK-NEXT: ret <2 x i1> [[R]] 545; 546 %c = call <2 x i1> @gen_v2i1() 547 %nota = xor <2 x i1> %a, <i1 true, i1 true> 548 %cond = or <2 x i1> %nota, %c 549 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 550 ret <2 x i1> %r 551} 552 553define <2 x i1> @and_or2_vec(<2 x i1> %a, <2 x i1> %b) { 554; CHECK-LABEL: @and_or2_vec( 555; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 556; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]] 557; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer 558; CHECK-NEXT: ret <2 x i1> [[R]] 559; 560 %c = call <2 x i1> @gen_v2i1() 561 %notc = xor <2 x i1> %c, <i1 true, i1 true> 562 %cond = and <2 x i1> %notc, %b 563 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 564 ret <2 x i1> %r 565} 566 567define <2 x i1> @and_or1_vec_commuted(<2 x i1> %a, <2 x i1> %b) { 568; CHECK-LABEL: @and_or1_vec_commuted( 569; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 570; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]] 571; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer 572; CHECK-NEXT: ret <2 x i1> [[R]] 573; 574 %c = call <2 x i1> @gen_v2i1() 575 %nota = xor <2 x i1> %a, <i1 true, i1 true> 576 %cond = or <2 x i1> %c, %nota 577 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 578 ret <2 x i1> %r 579} 580 581define <2 x i1> @and_or2_vec_commuted(<2 x i1> %a, <2 x i1> %b) { 582; CHECK-LABEL: @and_or2_vec_commuted( 583; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 584; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]] 585; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer 586; CHECK-NEXT: ret <2 x i1> [[R]] 587; 588 %c = call <2 x i1> @gen_v2i1() 589 %notc = xor <2 x i1> %c, <i1 true, i1 true> 590 %cond = and <2 x i1> %b, %notc 591 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 592 ret <2 x i1> %r 593} 594 595define i1 @and_or1_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) { 596; CHECK-LABEL: @and_or1_wrong_operand( 597; CHECK-NEXT: [[NOTA:%.*]] = xor i1 [[A:%.*]], true 598; CHECK-NEXT: [[COND:%.*]] = or i1 [[C:%.*]], [[NOTA]] 599; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]] 600; CHECK-NEXT: ret i1 [[R]] 601; 602 %nota = xor i1 %a, true 603 %cond = or i1 %nota, %c 604 %r = select i1 %cond, i1 %d, i1 %b 605 ret i1 %r 606} 607 608define i1 @and_or2_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) { 609; CHECK-LABEL: @and_or2_wrong_operand( 610; CHECK-NEXT: [[NOTC:%.*]] = xor i1 [[C:%.*]], true 611; CHECK-NEXT: [[COND:%.*]] = and i1 [[B:%.*]], [[NOTC]] 612; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]] 613; CHECK-NEXT: ret i1 [[R]] 614; 615 %notc = xor i1 %c, true 616 %cond = and i1 %notc, %b 617 %r = select i1 %cond, i1 %a, i1 %d 618 ret i1 %r 619} 620 621define i1 @and_or3(i1 %a, i1 %b, i32 %x, i32 %y) { 622; CHECK-LABEL: @and_or3( 623; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 624; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[A:%.*]] 625; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP2]], i1 false 626; CHECK-NEXT: ret i1 [[R]] 627; 628 %c = icmp eq i32 %x, %y 629 %cond = and i1 %b, %c 630 %r = select i1 %cond, i1 %a, i1 %b 631 ret i1 %r 632} 633 634define i1 @and_or3_commuted(i1 %a, i1 %b, i32 %x, i32 %y) { 635; CHECK-LABEL: @and_or3_commuted( 636; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 637; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[A:%.*]] 638; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP2]], i1 false 639; CHECK-NEXT: ret i1 [[R]] 640; 641 %c = icmp eq i32 %x, %y 642 %cond = and i1 %c, %b 643 %r = select i1 %cond, i1 %a, i1 %b 644 ret i1 %r 645} 646 647define i1 @and_or3_not_free_to_invert(i1 %a, i1 %b, i1 %c) { 648; CHECK-LABEL: @and_or3_not_free_to_invert( 649; CHECK-NEXT: [[COND:%.*]] = and i1 [[B:%.*]], [[C:%.*]] 650; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]] 651; CHECK-NEXT: ret i1 [[R]] 652; 653 %cond = and i1 %b, %c 654 %r = select i1 %cond, i1 %a, i1 %b 655 ret i1 %r 656} 657 658define i1 @and_or3_multiuse(i1 %a, i1 %b, i32 %x, i32 %y) { 659; CHECK-LABEL: @and_or3_multiuse( 660; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 661; CHECK-NEXT: [[COND:%.*]] = and i1 [[B:%.*]], [[C]] 662; CHECK-NEXT: call void @use(i1 [[COND]]) 663; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]] 664; CHECK-NEXT: ret i1 [[R]] 665; 666 %c = icmp eq i32 %x, %y 667 %cond = and i1 %b, %c 668 call void @use(i1 %cond) 669 %r = select i1 %cond, i1 %a, i1 %b 670 ret i1 %r 671} 672 673define <2 x i1> @and_or3_vec(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) { 674; CHECK-LABEL: @and_or3_vec( 675; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]] 676; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]] 677; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP2]], <2 x i1> zeroinitializer 678; CHECK-NEXT: ret <2 x i1> [[R]] 679; 680 %c = icmp eq <2 x i32> %x, %y 681 %cond = and <2 x i1> %b, %c 682 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 683 ret <2 x i1> %r 684} 685 686define <2 x i1> @and_or3_vec_commuted(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) { 687; CHECK-LABEL: @and_or3_vec_commuted( 688; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]] 689; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]] 690; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP2]], <2 x i1> zeroinitializer 691; CHECK-NEXT: ret <2 x i1> [[R]] 692; 693 %c = icmp eq <2 x i32> %x, %y 694 %cond = and <2 x i1> %c, %b 695 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 696 ret <2 x i1> %r 697} 698 699define i1 @and_or3_wrong_operand(i1 %a, i1 %b, i32 %x, i32 %y, i1 %d) { 700; CHECK-LABEL: @and_or3_wrong_operand( 701; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 702; CHECK-NEXT: [[COND:%.*]] = and i1 [[B:%.*]], [[C]] 703; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]] 704; CHECK-NEXT: ret i1 [[R]] 705; 706 %c = icmp eq i32 %x, %y 707 %cond = and i1 %b, %c 708 %r = select i1 %cond, i1 %a, i1 %d 709 ret i1 %r 710} 711 712define i1 @or_and1(i1 %a, i1 %b, i1 %c) { 713; CHECK-LABEL: @or_and1( 714; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false 715; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[TMP1]] 716; CHECK-NEXT: ret i1 [[R]] 717; 718 %notb = xor i1 %b, true 719 %cond = and i1 %notb, %c 720 %r = select i1 %cond, i1 %a, i1 %b 721 ret i1 %r 722} 723 724define i1 @or_and2(i1 %a, i1 %b, i1 %c) { 725; CHECK-LABEL: @or_and2( 726; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 false 727; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP1]] 728; CHECK-NEXT: ret i1 [[R]] 729; 730 %notc = xor i1 %c, true 731 %cond = or i1 %notc, %a 732 %r = select i1 %cond, i1 %a, i1 %b 733 ret i1 %r 734} 735 736define i1 @or_and1_commuted(i1 %a, i1 %b, i1 %c) { 737; CHECK-LABEL: @or_and1_commuted( 738; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false 739; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[TMP1]] 740; CHECK-NEXT: ret i1 [[R]] 741; 742 %notb = xor i1 %b, true 743 %cond = and i1 %c, %notb 744 %r = select i1 %cond, i1 %a, i1 %b 745 ret i1 %r 746} 747 748define i1 @or_and2_commuted(i1 %a, i1 %b, i1 %c) { 749; CHECK-LABEL: @or_and2_commuted( 750; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 false 751; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP1]] 752; CHECK-NEXT: ret i1 [[R]] 753; 754 %notc = xor i1 %c, true 755 %cond = or i1 %a, %notc 756 %r = select i1 %cond, i1 %a, i1 %b 757 ret i1 %r 758} 759 760define i1 @or_and1_multiuse(i1 %a, i1 %b, i1 %c) { 761; CHECK-LABEL: @or_and1_multiuse( 762; CHECK-NEXT: [[NOTB:%.*]] = xor i1 [[B:%.*]], true 763; CHECK-NEXT: [[COND:%.*]] = and i1 [[C:%.*]], [[NOTB]] 764; CHECK-NEXT: call void @use(i1 [[COND]]) 765; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]] 766; CHECK-NEXT: ret i1 [[R]] 767; 768 %notb = xor i1 %b, true 769 %cond = and i1 %notb, %c 770 call void @use(i1 %cond) 771 %r = select i1 %cond, i1 %a, i1 %b 772 ret i1 %r 773} 774 775define i1 @or_and2_multiuse(i1 %a, i1 %b, i1 %c) { 776; CHECK-LABEL: @or_and2_multiuse( 777; CHECK-NEXT: [[NOTC:%.*]] = xor i1 [[C:%.*]], true 778; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[NOTC]] 779; CHECK-NEXT: call void @use(i1 [[COND]]) 780; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]] 781; CHECK-NEXT: ret i1 [[R]] 782; 783 %notc = xor i1 %c, true 784 %cond = or i1 %notc, %a 785 call void @use(i1 %cond) 786 %r = select i1 %cond, i1 %a, i1 %b 787 ret i1 %r 788} 789 790define <2 x i1> @or_and1_vec(<2 x i1> %a, <2 x i1> %b) { 791; CHECK-LABEL: @or_and1_vec( 792; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 793; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer 794; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]] 795; CHECK-NEXT: ret <2 x i1> [[R]] 796; 797 %c = call <2 x i1> @gen_v2i1() 798 %notb = xor <2 x i1> %b, <i1 true, i1 true> 799 %cond = and <2 x i1> %c, %notb 800 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 801 ret <2 x i1> %r 802} 803 804define <2 x i1> @or_and2_vec(<2 x i1> %a, <2 x i1> %b) { 805; CHECK-LABEL: @or_and2_vec( 806; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 807; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 808; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]] 809; CHECK-NEXT: ret <2 x i1> [[R]] 810; 811 %c = call <2 x i1> @gen_v2i1() 812 %notc = xor <2 x i1> %c, <i1 true, i1 true> 813 %cond = or <2 x i1> %a, %notc 814 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 815 ret <2 x i1> %r 816} 817 818define <2 x i1> @or_and1_vec_commuted(<2 x i1> %a, <2 x i1> %b) { 819; CHECK-LABEL: @or_and1_vec_commuted( 820; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 821; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer 822; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]] 823; CHECK-NEXT: ret <2 x i1> [[R]] 824; 825 %c = call <2 x i1> @gen_v2i1() 826 %notb = xor <2 x i1> %b, <i1 true, i1 true> 827 %cond = and <2 x i1> %notb, %c 828 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 829 ret <2 x i1> %r 830} 831 832define <2 x i1> @or_and2_vec_commuted(<2 x i1> %a, <2 x i1> %b) { 833; CHECK-LABEL: @or_and2_vec_commuted( 834; CHECK-NEXT: [[C:%.*]] = call <2 x i1> @gen_v2i1() 835; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 836; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]] 837; CHECK-NEXT: ret <2 x i1> [[R]] 838; 839 %c = call <2 x i1> @gen_v2i1() 840 %notc = xor <2 x i1> %c, <i1 true, i1 true> 841 %cond = or <2 x i1> %notc, %a 842 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 843 ret <2 x i1> %r 844} 845 846define i1 @or_and1_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) { 847; CHECK-LABEL: @or_and1_wrong_operand( 848; CHECK-NEXT: [[NOTB:%.*]] = xor i1 [[B:%.*]], true 849; CHECK-NEXT: [[COND:%.*]] = and i1 [[C:%.*]], [[NOTB]] 850; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]] 851; CHECK-NEXT: ret i1 [[R]] 852; 853 %notb = xor i1 %b, true 854 %cond = and i1 %c, %notb 855 %r = select i1 %cond, i1 %a, i1 %d 856 ret i1 %r 857} 858 859define i1 @or_and2_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) { 860; CHECK-LABEL: @or_and2_wrong_operand( 861; CHECK-NEXT: [[NOTC:%.*]] = xor i1 [[C:%.*]], true 862; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[NOTC]] 863; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]] 864; CHECK-NEXT: ret i1 [[R]] 865; 866 %notc = xor i1 %c, true 867 %cond = or i1 %a, %notc 868 %r = select i1 %cond, i1 %d, i1 %b 869 ret i1 %r 870} 871 872define i1 @pr64558(i1 noundef %a, i1 noundef %b) { 873; CHECK-LABEL: @pr64558( 874; CHECK-NEXT: entry: 875; CHECK-NEXT: [[COND_V:%.*]] = or i1 [[B:%.*]], [[A:%.*]] 876; CHECK-NEXT: ret i1 [[COND_V]] 877; 878entry: 879 %lnot = xor i1 %b, true 880 %and11 = and i1 %lnot, %a 881 %cond.v = select i1 %and11, i1 %a, i1 %b 882 ret i1 %cond.v 883} 884 885define i1 @or_and3(i1 %a, i1 %b, i32 %x, i32 %y) { 886; CHECK-LABEL: @or_and3( 887; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 888; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 false 889; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP2]] 890; CHECK-NEXT: ret i1 [[R]] 891; 892 %c = icmp eq i32 %x, %y 893 %cond = or i1 %a, %c 894 %r = select i1 %cond, i1 %a, i1 %b 895 ret i1 %r 896} 897 898define i1 @or_and3_commuted(i1 %a, i1 %b, i32 %x, i32 %y) { 899; CHECK-LABEL: @or_and3_commuted( 900; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 901; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 false 902; CHECK-NEXT: [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP2]] 903; CHECK-NEXT: ret i1 [[R]] 904; 905 %c = icmp eq i32 %x, %y 906 %cond = or i1 %c, %a 907 %r = select i1 %cond, i1 %a, i1 %b 908 ret i1 %r 909} 910 911define i1 @or_and3_not_free_to_invert(i1 %a, i1 %b, i1 %c) { 912; CHECK-LABEL: @or_and3_not_free_to_invert( 913; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[C:%.*]] 914; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]] 915; CHECK-NEXT: ret i1 [[R]] 916; 917 %cond = or i1 %a, %c 918 %r = select i1 %cond, i1 %a, i1 %b 919 ret i1 %r 920} 921 922define i1 @or_and3_multiuse(i1 %a, i1 %b, i32 %x, i32 %y) { 923; CHECK-LABEL: @or_and3_multiuse( 924; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 925; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[C]] 926; CHECK-NEXT: call void @use(i1 [[COND]]) 927; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]] 928; CHECK-NEXT: ret i1 [[R]] 929; 930 %c = icmp eq i32 %x, %y 931 %cond = or i1 %a, %c 932 call void @use(i1 %cond) 933 %r = select i1 %cond, i1 %a, i1 %b 934 ret i1 %r 935} 936 937define <2 x i1> @or_and3_vec(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) { 938; CHECK-LABEL: @or_and3_vec( 939; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]] 940; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 941; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP2]] 942; CHECK-NEXT: ret <2 x i1> [[R]] 943; 944 %c = icmp eq <2 x i32> %x, %y 945 %cond = or <2 x i1> %a, %c 946 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 947 ret <2 x i1> %r 948} 949 950define <2 x i1> @or_and3_vec_commuted(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) { 951; CHECK-LABEL: @or_and3_vec_commuted( 952; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]] 953; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 954; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP2]] 955; CHECK-NEXT: ret <2 x i1> [[R]] 956; 957 %c = icmp eq <2 x i32> %x, %y 958 %cond = or <2 x i1> %c, %a 959 %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b 960 ret <2 x i1> %r 961} 962 963define i1 @or_and3_wrong_operand(i1 %a, i1 %b, i32 %x, i32 %y, i1 %d) { 964; CHECK-LABEL: @or_and3_wrong_operand( 965; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 966; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[C]] 967; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]] 968; CHECK-NEXT: ret i1 [[R]] 969; 970 %c = icmp eq i32 %x, %y 971 %cond = or i1 %a, %c 972 %r = select i1 %cond, i1 %d, i1 %b 973 ret i1 %r 974} 975 976define i8 @test_or_umax(i8 %x, i8 %y, i1 %cond) { 977; CHECK-LABEL: @test_or_umax( 978; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 979; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]] 980; CHECK-NEXT: ret i8 [[RET]] 981; 982 %cmp = icmp ugt i8 %x, %y 983 %or = select i1 %cond, i1 true, i1 %cmp 984 %ret = select i1 %or, i8 %x, i8 %y 985 ret i8 %ret 986} 987 988define i8 @test_or_umin(i8 %x, i8 %y, i1 %cond) { 989; CHECK-LABEL: @test_or_umin( 990; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 991; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[Y]], i8 [[TMP1]] 992; CHECK-NEXT: ret i8 [[RET]] 993; 994 %cmp = icmp ugt i8 %x, %y 995 %or = select i1 %cond, i1 true, i1 %cmp 996 %ret = select i1 %or, i8 %y, i8 %x 997 ret i8 %ret 998} 999 1000define i8 @test_and_umax(i8 %x, i8 %y, i1 %cond) { 1001; CHECK-LABEL: @test_and_umax( 1002; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1003; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[TMP1]], i8 [[Y]] 1004; CHECK-NEXT: ret i8 [[RET]] 1005; 1006 %cmp = icmp ugt i8 %x, %y 1007 %and = select i1 %cond, i1 %cmp, i1 false 1008 %ret = select i1 %and, i8 %x, i8 %y 1009 ret i8 %ret 1010} 1011 1012define i8 @test_and_umin(i8 %x, i8 %y, i1 %cond) { 1013; CHECK-LABEL: @test_and_umin( 1014; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1015; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[TMP1]], i8 [[X]] 1016; CHECK-NEXT: ret i8 [[RET]] 1017; 1018 %cmp = icmp ugt i8 %x, %y 1019 %and = select i1 %cond, i1 %cmp, i1 false 1020 %ret = select i1 %and, i8 %y, i8 %x 1021 ret i8 %ret 1022} 1023 1024define i8 @test_or_umax_bitwise1(i8 %x, i8 %y, i8 %val) { 1025; CHECK-LABEL: @test_or_umax_bitwise1( 1026; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0 1027; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1028; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND]], i8 [[X]], i8 [[TMP1]] 1029; CHECK-NEXT: ret i8 [[RET]] 1030; 1031 %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering 1032 %cmp = icmp ugt i8 %x, %y 1033 %or = or i1 %cond, %cmp 1034 %ret = select i1 %or, i8 %x, i8 %y 1035 ret i8 %ret 1036} 1037 1038define i8 @test_or_umax_bitwise2(i8 %x, i8 %y, i8 %val) { 1039; CHECK-LABEL: @test_or_umax_bitwise2( 1040; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0 1041; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1042; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND]], i8 [[X]], i8 [[TMP1]] 1043; CHECK-NEXT: ret i8 [[RET]] 1044; 1045 %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering 1046 %cmp = icmp ugt i8 %x, %y 1047 %or = or i1 %cmp, %cond 1048 %ret = select i1 %or, i8 %x, i8 %y 1049 ret i8 %ret 1050} 1051 1052define i8 @test_and_umax_bitwise1(i8 %x, i8 %y, i8 %val) { 1053; CHECK-LABEL: @test_and_umax_bitwise1( 1054; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0 1055; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1056; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND]], i8 [[TMP1]], i8 [[Y]] 1057; CHECK-NEXT: ret i8 [[RET]] 1058; 1059 %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering 1060 %cmp = icmp ugt i8 %x, %y 1061 %and = and i1 %cond, %cmp 1062 %ret = select i1 %and, i8 %x, i8 %y 1063 ret i8 %ret 1064} 1065 1066define i8 @test_and_umax_bitwise2(i8 %x, i8 %y, i8 %val) { 1067; CHECK-LABEL: @test_and_umax_bitwise2( 1068; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0 1069; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1070; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND]], i8 [[TMP1]], i8 [[Y]] 1071; CHECK-NEXT: ret i8 [[RET]] 1072; 1073 %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering 1074 %cmp = icmp ugt i8 %x, %y 1075 %and = and i1 %cmp, %cond 1076 %ret = select i1 %and, i8 %x, i8 %y 1077 ret i8 %ret 1078} 1079 1080; Other SPFs 1081 1082define i8 @test_or_smax(i8 %x, i8 %y, i1 %cond) { 1083; CHECK-LABEL: @test_or_smax( 1084; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) 1085; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]] 1086; CHECK-NEXT: ret i8 [[RET]] 1087; 1088 %cmp = icmp sgt i8 %x, %y 1089 %or = select i1 %cond, i1 true, i1 %cmp 1090 %ret = select i1 %or, i8 %x, i8 %y 1091 ret i8 %ret 1092} 1093 1094define i8 @test_or_abs(i8 %x, i1 %cond) { 1095; CHECK-LABEL: @test_or_abs( 1096; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true) 1097; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]] 1098; CHECK-NEXT: ret i8 [[RET]] 1099; 1100 %cmp = icmp sgt i8 %x, -1 1101 %neg = sub nsw i8 0, %x 1102 %or = select i1 %cond, i1 true, i1 %cmp 1103 %ret = select i1 %or, i8 %x, i8 %neg 1104 ret i8 %ret 1105} 1106 1107; TODO: fold SPF_FMAXNUM 1108define float @test_or_fmaxnum(float %x, float %y, i1 %cond) { 1109; CHECK-LABEL: @test_or_fmaxnum( 1110; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]] 1111; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]] 1112; CHECK-NEXT: [[RET:%.*]] = select i1 [[OR]], float [[X]], float [[Y]] 1113; CHECK-NEXT: ret float [[RET]] 1114; 1115 %cmp = fcmp nnan ogt float %x, %y 1116 %or = select i1 %cond, i1 true, i1 %cmp 1117 %ret = select i1 %or, float %x, float %y 1118 ret float %ret 1119} 1120 1121; Negative tests 1122 1123define i8 @test_or_umax_invalid_logical(i8 %x, i8 %y, i1 %cond) { 1124; CHECK-LABEL: @test_or_umax_invalid_logical( 1125; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]] 1126; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i1 true, i1 [[COND:%.*]] 1127; CHECK-NEXT: [[RET:%.*]] = select i1 [[OR]], i8 [[X]], i8 [[Y]] 1128; CHECK-NEXT: ret i8 [[RET]] 1129; 1130 %cmp = icmp ugt i8 %x, %y 1131 %or = select i1 %cmp, i1 true, i1 %cond 1132 %ret = select i1 %or, i8 %x, i8 %y 1133 ret i8 %ret 1134} 1135 1136define i8 @test_and_umax_invalid_logical(i8 %x, i8 %y, i1 %cond) { 1137; CHECK-LABEL: @test_and_umax_invalid_logical( 1138; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]] 1139; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP]], i1 [[COND:%.*]], i1 false 1140; CHECK-NEXT: [[RET:%.*]] = select i1 [[AND]], i8 [[X]], i8 [[Y]] 1141; CHECK-NEXT: ret i8 [[RET]] 1142; 1143 %cmp = icmp ugt i8 %x, %y 1144 %and = select i1 %cmp, i1 %cond, i1 false 1145 %ret = select i1 %and, i8 %x, i8 %y 1146 ret i8 %ret 1147} 1148 1149define i8 @test_or_umax_multiuse_cond(i8 %x, i8 %y, i1 %cond) { 1150; CHECK-LABEL: @test_or_umax_multiuse_cond( 1151; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]] 1152; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]] 1153; CHECK-NEXT: call void @use(i1 [[OR]]) 1154; CHECK-NEXT: [[RET:%.*]] = select i1 [[OR]], i8 [[X]], i8 [[Y]] 1155; CHECK-NEXT: ret i8 [[RET]] 1156; 1157 %cmp = icmp ugt i8 %x, %y 1158 %or = select i1 %cond, i1 true, i1 %cmp 1159 call void @use(i1 %or) 1160 %ret = select i1 %or, i8 %x, i8 %y 1161 ret i8 %ret 1162} 1163 1164; Tests from PR76203 1165 1166define i8 @test_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b) { 1167; CHECK-LABEL: @test_or_eq_a_b( 1168; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] 1169; CHECK-NEXT: ret i8 [[SELECT]] 1170; 1171 %cmp = icmp eq i8 %a, %b 1172 %cond = or i1 %other_cond, %cmp 1173 %select = select i1 %cond, i8 %a, i8 %b 1174 ret i8 %select 1175} 1176 1177define i8 @test_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b) { 1178; CHECK-LABEL: @test_and_ne_a_b( 1179; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] 1180; CHECK-NEXT: ret i8 [[SELECT]] 1181; 1182 %cmp = icmp ne i8 %a, %b 1183 %cond = and i1 %other_cond, %cmp 1184 %select = select i1 %cond, i8 %a, i8 %b 1185 ret i8 %select 1186} 1187 1188define i8 @test_or_eq_a_b_commuted(i1 %other_cond, i8 %a, i8 %b) { 1189; CHECK-LABEL: @test_or_eq_a_b_commuted( 1190; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[B:%.*]], i8 [[A:%.*]] 1191; CHECK-NEXT: ret i8 [[SELECT]] 1192; 1193 %cmp = icmp eq i8 %a, %b 1194 %cond = or i1 %other_cond, %cmp 1195 %select = select i1 %cond, i8 %b, i8 %a 1196 ret i8 %select 1197} 1198 1199define i8 @test_and_ne_a_b_commuted(i1 %other_cond, i8 %a, i8 %b) { 1200; CHECK-LABEL: @test_and_ne_a_b_commuted( 1201; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[B:%.*]], i8 [[A:%.*]] 1202; CHECK-NEXT: ret i8 [[SELECT]] 1203; 1204 %cmp = icmp ne i8 %a, %b 1205 %cond = and i1 %other_cond, %cmp 1206 %select = select i1 %cond, i8 %b, i8 %a 1207 ret i8 %select 1208} 1209 1210define i8 @test_or_eq_different_operands(i8 %a, i8 %b, i8 %c) { 1211; CHECK-LABEL: @test_or_eq_different_operands( 1212; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[C:%.*]] 1213; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[A]], i8 [[B:%.*]] 1214; CHECK-NEXT: ret i8 [[SELECT]] 1215; 1216 %cmp = icmp eq i8 %a, %c 1217 %cmp1 = icmp eq i8 %b, %a 1218 %cond = or i1 %cmp, %cmp1 1219 %select = select i1 %cond, i8 %a, i8 %b 1220 ret i8 %select 1221} 1222 1223define i8 @test_or_eq_a_b_multi_use(i1 %other_cond, i8 %a, i8 %b) { 1224; CHECK-LABEL: @test_or_eq_a_b_multi_use( 1225; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]] 1226; CHECK-NEXT: [[COND:%.*]] = or i1 [[OTHER_COND:%.*]], [[CMP]] 1227; CHECK-NEXT: call void @use(i1 [[CMP]]) 1228; CHECK-NEXT: call void @use(i1 [[COND]]) 1229; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND]], i8 [[A]], i8 [[B]] 1230; CHECK-NEXT: ret i8 [[SELECT]] 1231; 1232 %cmp = icmp eq i8 %a, %b 1233 %cond = or i1 %other_cond, %cmp 1234 call void @use(i1 %cmp) 1235 call void @use(i1 %cond) 1236 %select = select i1 %cond, i8 %a, i8 %b 1237 ret i8 %select 1238} 1239 1240define <2 x i8> @test_or_eq_a_b_vec(<2 x i1> %other_cond, <2 x i8> %a, <2 x i8> %b) { 1241; CHECK-LABEL: @test_or_eq_a_b_vec( 1242; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> [[OTHER_COND:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]] 1243; CHECK-NEXT: ret <2 x i8> [[SELECT]] 1244; 1245 %cmp = icmp eq <2 x i8> %a, %b 1246 %cond = or <2 x i1> %other_cond, %cmp 1247 %select = select <2 x i1> %cond, <2 x i8> %a, <2 x i8> %b 1248 ret <2 x i8> %select 1249} 1250 1251define i8 @test_or_ne_a_b(i1 %other_cond, i8 %a, i8 %b) { 1252; CHECK-LABEL: @test_or_ne_a_b( 1253; CHECK-NEXT: ret i8 [[A:%.*]] 1254; 1255 %cmp = icmp ne i8 %a, %b 1256 %cond = or i1 %other_cond, %cmp 1257 %select = select i1 %cond, i8 %a, i8 %b 1258 ret i8 %select 1259} 1260 1261define i8 @test_and_ne_different_operands_fail(i8 %a, i8 %b, i8 %c) { 1262; CHECK-LABEL: @test_and_ne_different_operands_fail( 1263; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A:%.*]], [[C:%.*]] 1264; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[B:%.*]], [[C]] 1265; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[CMP1]] 1266; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], i8 [[B]], i8 [[A]] 1267; CHECK-NEXT: ret i8 [[SELECT]] 1268; 1269 %cmp = icmp ne i8 %a, %c 1270 %cmp1 = icmp ne i8 %b, %c 1271 %cond = and i1 %cmp, %cmp1 1272 %select = select i1 %cond, i8 %b, i8 %a 1273 ret i8 %select 1274} 1275 1276define i8 @test_logical_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b) { 1277; CHECK-LABEL: @test_logical_or_eq_a_b( 1278; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] 1279; CHECK-NEXT: ret i8 [[SELECT]] 1280; 1281 %cmp = icmp eq i8 %a, %b 1282 %or.cond = select i1 %other_cond, i1 true, i1 %cmp 1283 %select = select i1 %or.cond, i8 %a, i8 %b 1284 ret i8 %select 1285} 1286 1287define i8 @test_logical_commuted_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b) { 1288; CHECK-LABEL: @test_logical_commuted_or_eq_a_b( 1289; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]] 1290; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[OTHER_COND:%.*]] 1291; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OR_COND]], i8 [[A]], i8 [[B]] 1292; CHECK-NEXT: ret i8 [[SELECT]] 1293; 1294 %cmp = icmp eq i8 %a, %b 1295 %or.cond = select i1 %cmp, i1 true, i1 %other_cond 1296 %select = select i1 %or.cond, i8 %a, i8 %b 1297 ret i8 %select 1298} 1299 1300define i8 @test_logical_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b) { 1301; CHECK-LABEL: @test_logical_and_ne_a_b( 1302; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] 1303; CHECK-NEXT: ret i8 [[SELECT]] 1304; 1305 %cmp = icmp ne i8 %a, %b 1306 %or.cond = select i1 %other_cond, i1 %cmp, i1 false 1307 %select = select i1 %or.cond, i8 %a, i8 %b 1308 ret i8 %select 1309} 1310 1311define i8 @test_logical_commuted_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b) { 1312; CHECK-LABEL: @test_logical_commuted_and_ne_a_b( 1313; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]] 1314; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[OTHER_COND:%.*]], i1 false 1315; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[OR_COND]], i8 [[A]], i8 [[B]] 1316; CHECK-NEXT: ret i8 [[SELECT]] 1317; 1318 %cmp = icmp ne i8 %a, %b 1319 %or.cond = select i1 %cmp, i1 %other_cond, i1 false 1320 %select = select i1 %or.cond, i8 %a, i8 %b 1321 ret i8 %select 1322} 1323