1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; TODO: All of these should be optimized to less than or equal to a single 5; instruction of select/and/or. 6 7; --- (A op B) op' A / (B op A) op' A --- 8 9; (A land B) land A 10define i1 @land_land_left1(i1 %A, i1 %B) { 11; CHECK-LABEL: @land_land_left1( 12; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 13; CHECK-NEXT: ret i1 [[C]] 14; 15 %c = select i1 %A, i1 %B, i1 false 16 %res = select i1 %c, i1 %A, i1 false 17 ret i1 %res 18} 19define i1 @land_land_left2(i1 %A, i1 %B) { 20; CHECK-LABEL: @land_land_left2( 21; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false 22; CHECK-NEXT: ret i1 [[RES]] 23; 24 %c = select i1 %B, i1 %A, i1 false 25 %res = select i1 %c, i1 %A, i1 false 26 ret i1 %res 27} 28 29; (A land B) band A 30define i1 @land_band_left1(i1 %A, i1 %B) { 31; CHECK-LABEL: @land_band_left1( 32; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 33; CHECK-NEXT: ret i1 [[C]] 34; 35 %c = select i1 %A, i1 %B, i1 false 36 %res = and i1 %c, %A 37 ret i1 %res 38} 39define i1 @land_band_left2(i1 %A, i1 %B) { 40; CHECK-LABEL: @land_band_left2( 41; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false 42; CHECK-NEXT: ret i1 [[C]] 43; 44 %c = select i1 %B, i1 %A, i1 false 45 %res = and i1 %c, %A 46 ret i1 %res 47} 48 49; (A land B) lor A 50define i1 @land_lor_left1(i1 %A, i1 %B) { 51; CHECK-LABEL: @land_lor_left1( 52; CHECK-NEXT: ret i1 [[A:%.*]] 53; 54 %c = select i1 %A, i1 %B, i1 false 55 %res = select i1 %c, i1 true, i1 %A 56 ret i1 %res 57} 58define i1 @land_lor_left2(i1 %A, i1 %B) { 59; CHECK-LABEL: @land_lor_left2( 60; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false 61; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 true, i1 [[A]] 62; CHECK-NEXT: ret i1 [[RES]] 63; 64 %c = select i1 %B, i1 %A, i1 false 65 %res = select i1 %c, i1 true, i1 %A 66 ret i1 %res 67} 68 69; (A land B) bor A 70define i1 @land_bor_left1(i1 %A, i1 %B) { 71; CHECK-LABEL: @land_bor_left1( 72; CHECK-NEXT: ret i1 [[A:%.*]] 73; 74 %c = select i1 %A, i1 %B, i1 false 75 %res = or i1 %c, %A 76 ret i1 %res 77} 78define i1 @land_bor_left2(i1 %A, i1 %B) { 79; CHECK-LABEL: @land_bor_left2( 80; CHECK-NEXT: ret i1 [[A:%.*]] 81; 82 %c = select i1 %B, i1 %A, i1 false 83 %res = or i1 %c, %A 84 ret i1 %res 85} 86 87; (A band B) land A 88define i1 @band_land_left1(i1 %A, i1 %B) { 89; CHECK-LABEL: @band_land_left1( 90; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]] 91; CHECK-NEXT: ret i1 [[C]] 92; 93 %c = and i1 %A, %B 94 %res = select i1 %c, i1 %A, i1 false 95 ret i1 %res 96} 97define i1 @band_land_left2(i1 %A, i1 %B) { 98; CHECK-LABEL: @band_land_left2( 99; CHECK-NEXT: [[C:%.*]] = and i1 [[B:%.*]], [[A:%.*]] 100; CHECK-NEXT: ret i1 [[C]] 101; 102 %c = and i1 %B, %A 103 %res = select i1 %c, i1 %A, i1 false 104 ret i1 %res 105} 106 107; (A band B) lor A 108define i1 @band_lor_left1(i1 %A, i1 %B) { 109; CHECK-LABEL: @band_lor_left1( 110; CHECK-NEXT: ret i1 [[A:%.*]] 111; 112 %c = and i1 %A, %B 113 %res = select i1 %c, i1 true, i1 %A 114 ret i1 %res 115} 116define i1 @band_lor_left2(i1 %A, i1 %B) { 117; CHECK-LABEL: @band_lor_left2( 118; CHECK-NEXT: ret i1 [[A:%.*]] 119; 120 %c = and i1 %B, %A 121 %res = select i1 %c, i1 true, i1 %A 122 ret i1 %res 123} 124 125; (A lor B) land A 126define i1 @lor_land_left1(i1 %A, i1 %B) { 127; CHECK-LABEL: @lor_land_left1( 128; CHECK-NEXT: ret i1 [[A:%.*]] 129; 130 %c = select i1 %A, i1 true, i1 %B 131 %res = select i1 %c, i1 %A, i1 false 132 ret i1 %res 133} 134define i1 @lor_land_left2(i1 %A, i1 %B) { 135; CHECK-LABEL: @lor_land_left2( 136; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] 137; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i1 [[A]], i1 false 138; CHECK-NEXT: ret i1 [[RES]] 139; 140 %c = select i1 %B, i1 true, i1 %A 141 %res = select i1 %c, i1 %A, i1 false 142 ret i1 %res 143} 144 145; (A lor B) band A 146define i1 @lor_band_left1(i1 %A, i1 %B) { 147; CHECK-LABEL: @lor_band_left1( 148; CHECK-NEXT: ret i1 [[A:%.*]] 149; 150 %c = select i1 %A, i1 true, i1 %B 151 %res = and i1 %c, %A 152 ret i1 %res 153} 154define i1 @lor_band_left2(i1 %A, i1 %B) { 155; CHECK-LABEL: @lor_band_left2( 156; CHECK-NEXT: ret i1 [[A:%.*]] 157; 158 %c = select i1 %B, i1 true, i1 %A 159 %res = and i1 %c, %A 160 ret i1 %res 161} 162 163; (A lor B) lor A 164define i1 @lor_lor_left1(i1 %A, i1 %B) { 165; CHECK-LABEL: @lor_lor_left1( 166; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 167; CHECK-NEXT: ret i1 [[C]] 168; 169 %c = select i1 %A, i1 true, i1 %B 170 %res = select i1 %c, i1 true, i1 %A 171 ret i1 %res 172} 173define i1 @lor_lor_left2(i1 %A, i1 %B) { 174; CHECK-LABEL: @lor_lor_left2( 175; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] 176; CHECK-NEXT: ret i1 [[RES]] 177; 178 %c = select i1 %B, i1 true, i1 %A 179 %res = select i1 %c, i1 true, i1 %A 180 ret i1 %res 181} 182 183; (A lor B) bor A 184define i1 @lor_bor_left1(i1 %A, i1 %B) { 185; CHECK-LABEL: @lor_bor_left1( 186; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 187; CHECK-NEXT: ret i1 [[C]] 188; 189 %c = select i1 %A, i1 true, i1 %B 190 %res = or i1 %c, %A 191 ret i1 %res 192} 193define i1 @lor_bor_left2(i1 %A, i1 %B) { 194; CHECK-LABEL: @lor_bor_left2( 195; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] 196; CHECK-NEXT: ret i1 [[C]] 197; 198 %c = select i1 %B, i1 true, i1 %A 199 %res = or i1 %c, %A 200 ret i1 %res 201} 202 203; (A bor B) land A 204define i1 @bor_land_left1(i1 %A, i1 %B) { 205; CHECK-LABEL: @bor_land_left1( 206; CHECK-NEXT: ret i1 [[A:%.*]] 207; 208 %c = or i1 %A, %B 209 %res = select i1 %c, i1 %A, i1 false 210 ret i1 %res 211} 212define i1 @bor_land_left2(i1 %A, i1 %B) { 213; CHECK-LABEL: @bor_land_left2( 214; CHECK-NEXT: ret i1 [[A:%.*]] 215; 216 %c = or i1 %B, %A 217 %res = select i1 %c, i1 %A, i1 false 218 ret i1 %res 219} 220 221; (A bor B) lor A 222define i1 @bor_lor_left1(i1 %A, i1 %B) { 223; CHECK-LABEL: @bor_lor_left1( 224; CHECK-NEXT: [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]] 225; CHECK-NEXT: ret i1 [[C]] 226; 227 %c = or i1 %A, %B 228 %res = select i1 %c, i1 true, i1 %A 229 ret i1 %res 230} 231define i1 @bor_lor_left2(i1 %A, i1 %B) { 232; CHECK-LABEL: @bor_lor_left2( 233; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], [[A:%.*]] 234; CHECK-NEXT: ret i1 [[C]] 235; 236 %c = or i1 %B, %A 237 %res = select i1 %c, i1 true, i1 %A 238 ret i1 %res 239} 240 241; --- A op (A op' B) / A op (B op' A) --- 242 243; A land (A land B) 244define i1 @land_land_right1(i1 %A, i1 %B) { 245; CHECK-LABEL: @land_land_right1( 246; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 247; CHECK-NEXT: ret i1 [[RES]] 248; 249 %c = select i1 %A, i1 %B, i1 false 250 %res = select i1 %A, i1 %c, i1 false 251 ret i1 %res 252} 253define i1 @land_land_right2(i1 %A, i1 %B) { 254; CHECK-LABEL: @land_land_right2( 255; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 256; CHECK-NEXT: ret i1 [[RES]] 257; 258 %c = select i1 %B, i1 %A, i1 false 259 %res = select i1 %A, i1 %c, i1 false 260 ret i1 %res 261} 262 263; A band (A land B) 264define i1 @land_band_right1(i1 %A, i1 %B) { 265; CHECK-LABEL: @land_band_right1( 266; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 267; CHECK-NEXT: ret i1 [[C]] 268; 269 %c = select i1 %A, i1 %B, i1 false 270 %res = and i1 %A, %c 271 ret i1 %res 272} 273define i1 @land_band_right2(i1 %A, i1 %B) { 274; CHECK-LABEL: @land_band_right2( 275; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false 276; CHECK-NEXT: ret i1 [[C]] 277; 278 %c = select i1 %B, i1 %A, i1 false 279 %res = and i1 %A, %c 280 ret i1 %res 281} 282 283; A lor (A land B) 284define i1 @land_lor_right1(i1 %A, i1 %B) { 285; CHECK-LABEL: @land_lor_right1( 286; CHECK-NEXT: ret i1 [[A:%.*]] 287; 288 %c = select i1 %A, i1 %B, i1 false 289 %res = select i1 %A, i1 true, i1 %c 290 ret i1 %res 291} 292define i1 @land_lor_right2(i1 %A, i1 %B) { 293; CHECK-LABEL: @land_lor_right2( 294; CHECK-NEXT: ret i1 [[A:%.*]] 295; 296 %c = select i1 %B, i1 %A, i1 false 297 %res = select i1 %A, i1 true, i1 %c 298 ret i1 %res 299} 300 301; A bor (A land B) 302define i1 @land_bor_right1(i1 %A, i1 %B) { 303; CHECK-LABEL: @land_bor_right1( 304; CHECK-NEXT: ret i1 [[A:%.*]] 305; 306 %c = select i1 %A, i1 %B, i1 false 307 %res = or i1 %A, %c 308 ret i1 %res 309} 310define i1 @land_bor_right2(i1 %A, i1 %B) { 311; CHECK-LABEL: @land_bor_right2( 312; CHECK-NEXT: ret i1 [[A:%.*]] 313; 314 %c = select i1 %B, i1 %A, i1 false 315 %res = or i1 %A, %c 316 ret i1 %res 317} 318 319; A land (A band B) 320define i1 @band_land_right1(i1 %A, i1 %B) { 321; CHECK-LABEL: @band_land_right1( 322; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 323; CHECK-NEXT: ret i1 [[RES]] 324; 325 %c = and i1 %A, %B 326 %res = select i1 %A, i1 %c, i1 false 327 ret i1 %res 328} 329define i1 @band_land_right2(i1 %A, i1 %B) { 330; CHECK-LABEL: @band_land_right2( 331; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 332; CHECK-NEXT: ret i1 [[RES]] 333; 334 %c = and i1 %B, %A 335 %res = select i1 %A, i1 %c, i1 false 336 ret i1 %res 337} 338 339; A lor (A band B) 340define i1 @band_lor_right1(i1 %A, i1 %B) { 341; CHECK-LABEL: @band_lor_right1( 342; CHECK-NEXT: ret i1 [[A:%.*]] 343; 344 %c = and i1 %A, %B 345 %res = select i1 %A, i1 true, i1 %c 346 ret i1 %res 347} 348define i1 @band_lor_right2(i1 %A, i1 %B) { 349; CHECK-LABEL: @band_lor_right2( 350; CHECK-NEXT: ret i1 [[A:%.*]] 351; 352 %c = and i1 %B, %A 353 %res = select i1 %A, i1 true, i1 %c 354 ret i1 %res 355} 356 357; A land (A lor B) 358define i1 @lor_land_right1(i1 %A, i1 %B) { 359; CHECK-LABEL: @lor_land_right1( 360; CHECK-NEXT: ret i1 [[A:%.*]] 361; 362 %c = select i1 %A, i1 true, i1 %B 363 %res = select i1 %A, i1 %c, i1 false 364 ret i1 %res 365} 366define i1 @lor_land_right2(i1 %A, i1 %B) { 367; CHECK-LABEL: @lor_land_right2( 368; CHECK-NEXT: ret i1 [[A:%.*]] 369; 370 %c = select i1 %B, i1 true, i1 %A 371 %res = select i1 %A, i1 %c, i1 false 372 ret i1 %res 373} 374 375; A band (A lor B) 376define i1 @lor_band_right1(i1 %A, i1 %B) { 377; CHECK-LABEL: @lor_band_right1( 378; CHECK-NEXT: ret i1 [[A:%.*]] 379; 380 %c = select i1 %A, i1 true, i1 %B 381 %res = and i1 %A, %c 382 ret i1 %res 383} 384define i1 @lor_band_right2(i1 %A, i1 %B) { 385; CHECK-LABEL: @lor_band_right2( 386; CHECK-NEXT: ret i1 [[A:%.*]] 387; 388 %c = select i1 %B, i1 true, i1 %A 389 %res = and i1 %A, %c 390 ret i1 %res 391} 392 393; A lor (A lor B) 394define i1 @lor_lor_right1(i1 %A, i1 %B) { 395; CHECK-LABEL: @lor_lor_right1( 396; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 397; CHECK-NEXT: ret i1 [[RES]] 398; 399 %c = select i1 %A, i1 true, i1 %B 400 %res = select i1 %A, i1 true, i1 %c 401 ret i1 %res 402} 403define i1 @lor_lor_right2(i1 %A, i1 %B) { 404; CHECK-LABEL: @lor_lor_right2( 405; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 406; CHECK-NEXT: ret i1 [[RES]] 407; 408 %c = select i1 %B, i1 true, i1 %A 409 %res = select i1 %A, i1 true, i1 %c 410 ret i1 %res 411} 412 413; A bor (A lor B) 414define i1 @lor_bor_right1(i1 %A, i1 %B) { 415; CHECK-LABEL: @lor_bor_right1( 416; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 417; CHECK-NEXT: ret i1 [[C]] 418; 419 %c = select i1 %A, i1 true, i1 %B 420 %res = or i1 %A, %c 421 ret i1 %res 422} 423define i1 @lor_bor_right2(i1 %A, i1 %B) { 424; CHECK-LABEL: @lor_bor_right2( 425; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] 426; CHECK-NEXT: ret i1 [[C]] 427; 428 %c = select i1 %B, i1 true, i1 %A 429 %res = or i1 %A, %c 430 ret i1 %res 431} 432 433; A land (A bor B) 434define i1 @bor_land_right1(i1 %A, i1 %B) { 435; CHECK-LABEL: @bor_land_right1( 436; CHECK-NEXT: ret i1 [[A:%.*]] 437; 438 %c = or i1 %A, %B 439 %res = select i1 %A, i1 %c, i1 false 440 ret i1 %res 441} 442define i1 @bor_land_right2(i1 %A, i1 %B) { 443; CHECK-LABEL: @bor_land_right2( 444; CHECK-NEXT: ret i1 [[A:%.*]] 445; 446 %c = or i1 %B, %A 447 %res = select i1 %A, i1 %c, i1 false 448 ret i1 %res 449} 450 451; A lor (A bor B) 452define i1 @bor_lor_right1(i1 %A, i1 %B) { 453; CHECK-LABEL: @bor_lor_right1( 454; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 455; CHECK-NEXT: ret i1 [[RES]] 456; 457 %c = or i1 %A, %B 458 %res = select i1 %A, i1 true, i1 %c 459 ret i1 %res 460} 461define i1 @bor_lor_right2(i1 %A, i1 %B) { 462; CHECK-LABEL: @bor_lor_right2( 463; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] 464; CHECK-NEXT: ret i1 [[RES]] 465; 466 %c = or i1 %B, %A 467 %res = select i1 %A, i1 true, i1 %c 468 ret i1 %res 469} 470 471; Value equivalence substitution does not account for vector 472; transforms, so it needs a scalar condition operand. 473; For example, this would miscompile if %a = {1, 0}. 474 475define <2 x i1> @PR50500_trueval(<2 x i1> %a, <2 x i1> %b) { 476; CHECK-LABEL: @PR50500_trueval( 477; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0> 478; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[S]], <2 x i1> [[B:%.*]] 479; CHECK-NEXT: ret <2 x i1> [[R]] 480; 481 %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0> 482 %r = select <2 x i1> %a, <2 x i1> %s, <2 x i1> %b 483 ret <2 x i1> %r 484} 485 486define <2 x i1> @PR50500_falseval(<2 x i1> %a, <2 x i1> %b) { 487; CHECK-LABEL: @PR50500_falseval( 488; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0> 489; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B:%.*]], <2 x i1> [[S]] 490; CHECK-NEXT: ret <2 x i1> [[R]] 491; 492 %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0> 493 %r = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %s 494 ret <2 x i1> %r 495} 496