1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs -mattr=+isel | FileCheck %s --check-prefix=ALL --check-prefix=ISEL 3; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs -mattr=-isel | FileCheck %s --check-prefix=ALL --check-prefix=NO_ISEL 4 5; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?). 6; Test the zeroext/signext variants of each pattern to see if that makes a difference. 7 8; select Cond, 0, 1 --> zext (!Cond) 9 10define i32 @select_0_or_1(i1 %cond) { 11; ALL-LABEL: select_0_or_1: 12; ALL: # BB#0: 13; ALL-NEXT: not 3, 3 14; ALL-NEXT: clrldi 3, 3, 63 15; ALL-NEXT: blr 16 %sel = select i1 %cond, i32 0, i32 1 17 ret i32 %sel 18} 19 20define i32 @select_0_or_1_zeroext(i1 zeroext %cond) { 21; ALL-LABEL: select_0_or_1_zeroext: 22; ALL: # BB#0: 23; ALL-NEXT: xori 3, 3, 1 24; ALL-NEXT: blr 25 %sel = select i1 %cond, i32 0, i32 1 26 ret i32 %sel 27} 28 29define i32 @select_0_or_1_signext(i1 signext %cond) { 30; ALL-LABEL: select_0_or_1_signext: 31; ALL: # BB#0: 32; ALL-NEXT: not 3, 3 33; ALL-NEXT: clrldi 3, 3, 63 34; ALL-NEXT: blr 35 %sel = select i1 %cond, i32 0, i32 1 36 ret i32 %sel 37} 38 39; select Cond, 1, 0 --> zext (Cond) 40 41define i32 @select_1_or_0(i1 %cond) { 42; ISEL-LABEL: select_1_or_0: 43; ISEL: # BB#0: 44; ISEL-NEXT: andi. 3, 3, 1 45; ISEL-NEXT: li 4, 1 46; ISEL-NEXT: li 3, 0 47; ISEL-NEXT: isel 3, 4, 3, 1 48; ISEL-NEXT: blr 49; 50; NO_ISEL-LABEL: select_1_or_0: 51; NO_ISEL: # BB#0: 52; NO_ISEL-NEXT: andi. 3, 3, 1 53; NO_ISEL-NEXT: li 4, 1 54; NO_ISEL-NEXT: li 3, 0 55; NO_ISEL-NEXT: bc 12, 1, .LBB3_1 56; NO_ISEL-NEXT: blr 57; NO_ISEL-NEXT: .LBB3_1: 58; NO_ISEL-NEXT: addi 3, 4, 0 59; NO_ISEL-NEXT: blr 60 %sel = select i1 %cond, i32 1, i32 0 61 ret i32 %sel 62} 63 64define i32 @select_1_or_0_zeroext(i1 zeroext %cond) { 65; ISEL-LABEL: select_1_or_0_zeroext: 66; ISEL: # BB#0: 67; ISEL-NEXT: andi. 3, 3, 1 68; ISEL-NEXT: li 4, 1 69; ISEL-NEXT: li 3, 0 70; ISEL-NEXT: isel 3, 4, 3, 1 71; ISEL-NEXT: blr 72; 73; NO_ISEL-LABEL: select_1_or_0_zeroext: 74; NO_ISEL: # BB#0: 75; NO_ISEL-NEXT: andi. 3, 3, 1 76; NO_ISEL-NEXT: li 4, 1 77; NO_ISEL-NEXT: li 3, 0 78; NO_ISEL-NEXT: bc 12, 1, .LBB4_1 79; NO_ISEL-NEXT: blr 80; NO_ISEL-NEXT: .LBB4_1: 81; NO_ISEL-NEXT: addi 3, 4, 0 82; NO_ISEL-NEXT: blr 83 %sel = select i1 %cond, i32 1, i32 0 84 ret i32 %sel 85} 86 87define i32 @select_1_or_0_signext(i1 signext %cond) { 88; ISEL-LABEL: select_1_or_0_signext: 89; ISEL: # BB#0: 90; ISEL-NEXT: andi. 3, 3, 1 91; ISEL-NEXT: li 4, 1 92; ISEL-NEXT: li 3, 0 93; ISEL-NEXT: isel 3, 4, 3, 1 94; ISEL-NEXT: blr 95; 96; NO_ISEL-LABEL: select_1_or_0_signext: 97; NO_ISEL: # BB#0: 98; NO_ISEL-NEXT: andi. 3, 3, 1 99; NO_ISEL-NEXT: li 4, 1 100; NO_ISEL-NEXT: li 3, 0 101; NO_ISEL-NEXT: bc 12, 1, .LBB5_1 102; NO_ISEL-NEXT: blr 103; NO_ISEL-NEXT: .LBB5_1: 104; NO_ISEL-NEXT: addi 3, 4, 0 105; NO_ISEL-NEXT: blr 106 %sel = select i1 %cond, i32 1, i32 0 107 ret i32 %sel 108} 109 110; select Cond, 0, -1 --> sext (!Cond) 111 112define i32 @select_0_or_neg1(i1 %cond) { 113; ISEL-LABEL: select_0_or_neg1: 114; ISEL: # BB#0: 115; ISEL-NEXT: li 4, 0 116; ISEL-NEXT: andi. 3, 3, 1 117; ISEL-NEXT: oris 3, 4, 65535 118; ISEL-NEXT: ori 3, 3, 65535 119; ISEL-NEXT: isel 3, 0, 3, 1 120; ISEL-NEXT: blr 121; 122; NO_ISEL-LABEL: select_0_or_neg1: 123; NO_ISEL: # BB#0: 124; NO_ISEL-NEXT: li 4, 0 125; NO_ISEL-NEXT: andi. 3, 3, 1 126; NO_ISEL-NEXT: oris 3, 4, 65535 127; NO_ISEL-NEXT: ori 3, 3, 65535 128; NO_ISEL-NEXT: bc 12, 1, .LBB6_1 129; NO_ISEL-NEXT: blr 130; NO_ISEL-NEXT: .LBB6_1: 131; NO_ISEL-NEXT: addi 3, 0, 0 132; NO_ISEL-NEXT: blr 133 %sel = select i1 %cond, i32 0, i32 -1 134 ret i32 %sel 135} 136 137define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) { 138; ISEL-LABEL: select_0_or_neg1_zeroext: 139; ISEL: # BB#0: 140; ISEL-NEXT: li 4, 0 141; ISEL-NEXT: andi. 3, 3, 1 142; ISEL-NEXT: oris 3, 4, 65535 143; ISEL-NEXT: ori 3, 3, 65535 144; ISEL-NEXT: isel 3, 0, 3, 1 145; ISEL-NEXT: blr 146; 147; NO_ISEL-LABEL: select_0_or_neg1_zeroext: 148; NO_ISEL: # BB#0: 149; NO_ISEL-NEXT: li 4, 0 150; NO_ISEL-NEXT: andi. 3, 3, 1 151; NO_ISEL-NEXT: oris 3, 4, 65535 152; NO_ISEL-NEXT: ori 3, 3, 65535 153; NO_ISEL-NEXT: bc 12, 1, .LBB7_1 154; NO_ISEL-NEXT: blr 155; NO_ISEL-NEXT: .LBB7_1: 156; NO_ISEL-NEXT: addi 3, 0, 0 157; NO_ISEL-NEXT: blr 158 %sel = select i1 %cond, i32 0, i32 -1 159 ret i32 %sel 160} 161 162define i32 @select_0_or_neg1_signext(i1 signext %cond) { 163; ISEL-LABEL: select_0_or_neg1_signext: 164; ISEL: # BB#0: 165; ISEL-NEXT: li 4, 0 166; ISEL-NEXT: andi. 3, 3, 1 167; ISEL-NEXT: oris 3, 4, 65535 168; ISEL-NEXT: ori 3, 3, 65535 169; ISEL-NEXT: isel 3, 0, 3, 1 170; ISEL-NEXT: blr 171; 172; NO_ISEL-LABEL: select_0_or_neg1_signext: 173; NO_ISEL: # BB#0: 174; NO_ISEL-NEXT: li 4, 0 175; NO_ISEL-NEXT: andi. 3, 3, 1 176; NO_ISEL-NEXT: oris 3, 4, 65535 177; NO_ISEL-NEXT: ori 3, 3, 65535 178; NO_ISEL-NEXT: bc 12, 1, .LBB8_1 179; NO_ISEL-NEXT: blr 180; NO_ISEL-NEXT: .LBB8_1: 181; NO_ISEL-NEXT: addi 3, 0, 0 182; NO_ISEL-NEXT: blr 183 %sel = select i1 %cond, i32 0, i32 -1 184 ret i32 %sel 185} 186 187; select Cond, -1, 0 --> sext (Cond) 188 189define i32 @select_neg1_or_0(i1 %cond) { 190; ISEL-LABEL: select_neg1_or_0: 191; ISEL: # BB#0: 192; ISEL-NEXT: li 4, 0 193; ISEL-NEXT: andi. 3, 3, 1 194; ISEL-NEXT: oris 3, 4, 65535 195; ISEL-NEXT: ori 3, 3, 65535 196; ISEL-NEXT: isel 3, 3, 4, 1 197; ISEL-NEXT: blr 198; 199; NO_ISEL-LABEL: select_neg1_or_0: 200; NO_ISEL: # BB#0: 201; NO_ISEL-NEXT: li 4, 0 202; NO_ISEL-NEXT: andi. 3, 3, 1 203; NO_ISEL-NEXT: oris 3, 4, 65535 204; NO_ISEL-NEXT: ori 3, 3, 65535 205; NO_ISEL-NEXT: bclr 12, 1, 0 206; NO_ISEL-NEXT: # BB#1: 207; NO_ISEL-NEXT: ori 3, 4, 0 208; NO_ISEL-NEXT: blr 209 %sel = select i1 %cond, i32 -1, i32 0 210 ret i32 %sel 211} 212 213define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) { 214; ISEL-LABEL: select_neg1_or_0_zeroext: 215; ISEL: # BB#0: 216; ISEL-NEXT: li 4, 0 217; ISEL-NEXT: andi. 3, 3, 1 218; ISEL-NEXT: oris 3, 4, 65535 219; ISEL-NEXT: ori 3, 3, 65535 220; ISEL-NEXT: isel 3, 3, 4, 1 221; ISEL-NEXT: blr 222; 223; NO_ISEL-LABEL: select_neg1_or_0_zeroext: 224; NO_ISEL: # BB#0: 225; NO_ISEL-NEXT: li 4, 0 226; NO_ISEL-NEXT: andi. 3, 3, 1 227; NO_ISEL-NEXT: oris 3, 4, 65535 228; NO_ISEL-NEXT: ori 3, 3, 65535 229; NO_ISEL-NEXT: bclr 12, 1, 0 230; NO_ISEL-NEXT: # BB#1: 231; NO_ISEL-NEXT: ori 3, 4, 0 232; NO_ISEL-NEXT: blr 233 %sel = select i1 %cond, i32 -1, i32 0 234 ret i32 %sel 235} 236 237define i32 @select_neg1_or_0_signext(i1 signext %cond) { 238; ISEL-LABEL: select_neg1_or_0_signext: 239; ISEL: # BB#0: 240; ISEL-NEXT: li 4, 0 241; ISEL-NEXT: andi. 3, 3, 1 242; ISEL-NEXT: oris 3, 4, 65535 243; ISEL-NEXT: ori 3, 3, 65535 244; ISEL-NEXT: isel 3, 3, 4, 1 245; ISEL-NEXT: blr 246; 247; NO_ISEL-LABEL: select_neg1_or_0_signext: 248; NO_ISEL: # BB#0: 249; NO_ISEL-NEXT: li 4, 0 250; NO_ISEL-NEXT: andi. 3, 3, 1 251; NO_ISEL-NEXT: oris 3, 4, 65535 252; NO_ISEL-NEXT: ori 3, 3, 65535 253; NO_ISEL-NEXT: bclr 12, 1, 0 254; NO_ISEL-NEXT: # BB#1: 255; NO_ISEL-NEXT: ori 3, 4, 0 256; NO_ISEL-NEXT: blr 257 %sel = select i1 %cond, i32 -1, i32 0 258 ret i32 %sel 259} 260 261; select Cond, C+1, C --> add (zext Cond), C 262 263define i32 @select_Cplus1_C(i1 %cond) { 264; ISEL-LABEL: select_Cplus1_C: 265; ISEL: # BB#0: 266; ISEL-NEXT: andi. 3, 3, 1 267; ISEL-NEXT: li 4, 42 268; ISEL-NEXT: li 3, 41 269; ISEL-NEXT: isel 3, 4, 3, 1 270; ISEL-NEXT: blr 271; 272; NO_ISEL-LABEL: select_Cplus1_C: 273; NO_ISEL: # BB#0: 274; NO_ISEL-NEXT: andi. 3, 3, 1 275; NO_ISEL-NEXT: li 4, 42 276; NO_ISEL-NEXT: li 3, 41 277; NO_ISEL-NEXT: bc 12, 1, .LBB12_1 278; NO_ISEL-NEXT: blr 279; NO_ISEL-NEXT: .LBB12_1: 280; NO_ISEL-NEXT: addi 3, 4, 0 281; NO_ISEL-NEXT: blr 282 %sel = select i1 %cond, i32 42, i32 41 283 ret i32 %sel 284} 285 286define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) { 287; ISEL-LABEL: select_Cplus1_C_zeroext: 288; ISEL: # BB#0: 289; ISEL-NEXT: andi. 3, 3, 1 290; ISEL-NEXT: li 4, 42 291; ISEL-NEXT: li 3, 41 292; ISEL-NEXT: isel 3, 4, 3, 1 293; ISEL-NEXT: blr 294; 295; NO_ISEL-LABEL: select_Cplus1_C_zeroext: 296; NO_ISEL: # BB#0: 297; NO_ISEL-NEXT: andi. 3, 3, 1 298; NO_ISEL-NEXT: li 4, 42 299; NO_ISEL-NEXT: li 3, 41 300; NO_ISEL-NEXT: bc 12, 1, .LBB13_1 301; NO_ISEL-NEXT: blr 302; NO_ISEL-NEXT: .LBB13_1: 303; NO_ISEL-NEXT: addi 3, 4, 0 304; NO_ISEL-NEXT: blr 305 %sel = select i1 %cond, i32 42, i32 41 306 ret i32 %sel 307} 308 309define i32 @select_Cplus1_C_signext(i1 signext %cond) { 310; ISEL-LABEL: select_Cplus1_C_signext: 311; ISEL: # BB#0: 312; ISEL-NEXT: andi. 3, 3, 1 313; ISEL-NEXT: li 4, 42 314; ISEL-NEXT: li 3, 41 315; ISEL-NEXT: isel 3, 4, 3, 1 316; ISEL-NEXT: blr 317; 318; NO_ISEL-LABEL: select_Cplus1_C_signext: 319; NO_ISEL: # BB#0: 320; NO_ISEL-NEXT: andi. 3, 3, 1 321; NO_ISEL-NEXT: li 4, 42 322; NO_ISEL-NEXT: li 3, 41 323; NO_ISEL-NEXT: bc 12, 1, .LBB14_1 324; NO_ISEL-NEXT: blr 325; NO_ISEL-NEXT: .LBB14_1: 326; NO_ISEL-NEXT: addi 3, 4, 0 327; NO_ISEL-NEXT: blr 328 %sel = select i1 %cond, i32 42, i32 41 329 ret i32 %sel 330} 331 332; select Cond, C, C+1 --> add (sext Cond), C 333 334define i32 @select_C_Cplus1(i1 %cond) { 335; ISEL-LABEL: select_C_Cplus1: 336; ISEL: # BB#0: 337; ISEL-NEXT: andi. 3, 3, 1 338; ISEL-NEXT: li 4, 41 339; ISEL-NEXT: li 3, 42 340; ISEL-NEXT: isel 3, 4, 3, 1 341; ISEL-NEXT: blr 342; 343; NO_ISEL-LABEL: select_C_Cplus1: 344; NO_ISEL: # BB#0: 345; NO_ISEL-NEXT: andi. 3, 3, 1 346; NO_ISEL-NEXT: li 4, 41 347; NO_ISEL-NEXT: li 3, 42 348; NO_ISEL-NEXT: bc 12, 1, .LBB15_1 349; NO_ISEL-NEXT: blr 350; NO_ISEL-NEXT: .LBB15_1: 351; NO_ISEL-NEXT: addi 3, 4, 0 352; NO_ISEL-NEXT: blr 353 %sel = select i1 %cond, i32 41, i32 42 354 ret i32 %sel 355} 356 357define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) { 358; ISEL-LABEL: select_C_Cplus1_zeroext: 359; ISEL: # BB#0: 360; ISEL-NEXT: andi. 3, 3, 1 361; ISEL-NEXT: li 4, 41 362; ISEL-NEXT: li 3, 42 363; ISEL-NEXT: isel 3, 4, 3, 1 364; ISEL-NEXT: blr 365; 366; NO_ISEL-LABEL: select_C_Cplus1_zeroext: 367; NO_ISEL: # BB#0: 368; NO_ISEL-NEXT: andi. 3, 3, 1 369; NO_ISEL-NEXT: li 4, 41 370; NO_ISEL-NEXT: li 3, 42 371; NO_ISEL-NEXT: bc 12, 1, .LBB16_1 372; NO_ISEL-NEXT: blr 373; NO_ISEL-NEXT: .LBB16_1: 374; NO_ISEL-NEXT: addi 3, 4, 0 375; NO_ISEL-NEXT: blr 376 %sel = select i1 %cond, i32 41, i32 42 377 ret i32 %sel 378} 379 380define i32 @select_C_Cplus1_signext(i1 signext %cond) { 381; ISEL-LABEL: select_C_Cplus1_signext: 382; ISEL: # BB#0: 383; ISEL-NEXT: andi. 3, 3, 1 384; ISEL-NEXT: li 4, 41 385; ISEL-NEXT: li 3, 42 386; ISEL-NEXT: isel 3, 4, 3, 1 387; ISEL-NEXT: blr 388; 389; NO_ISEL-LABEL: select_C_Cplus1_signext: 390; NO_ISEL: # BB#0: 391; NO_ISEL-NEXT: andi. 3, 3, 1 392; NO_ISEL-NEXT: li 4, 41 393; NO_ISEL-NEXT: li 3, 42 394; NO_ISEL-NEXT: bc 12, 1, .LBB17_1 395; NO_ISEL-NEXT: blr 396; NO_ISEL-NEXT: .LBB17_1: 397; NO_ISEL-NEXT: addi 3, 4, 0 398; NO_ISEL-NEXT: blr 399 %sel = select i1 %cond, i32 41, i32 42 400 ret i32 %sel 401} 402 403; In general, select of 2 constants could be: 404; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2 405 406define i32 @select_C1_C2(i1 %cond) { 407; ISEL-LABEL: select_C1_C2: 408; ISEL: # BB#0: 409; ISEL-NEXT: andi. 3, 3, 1 410; ISEL-NEXT: li 4, 421 411; ISEL-NEXT: li 3, 42 412; ISEL-NEXT: isel 3, 4, 3, 1 413; ISEL-NEXT: blr 414; 415; NO_ISEL-LABEL: select_C1_C2: 416; NO_ISEL: # BB#0: 417; NO_ISEL-NEXT: andi. 3, 3, 1 418; NO_ISEL-NEXT: li 4, 421 419; NO_ISEL-NEXT: li 3, 42 420; NO_ISEL-NEXT: bc 12, 1, .LBB18_1 421; NO_ISEL-NEXT: blr 422; NO_ISEL-NEXT: .LBB18_1: 423; NO_ISEL-NEXT: addi 3, 4, 0 424; NO_ISEL-NEXT: blr 425 %sel = select i1 %cond, i32 421, i32 42 426 ret i32 %sel 427} 428 429define i32 @select_C1_C2_zeroext(i1 zeroext %cond) { 430; ISEL-LABEL: select_C1_C2_zeroext: 431; ISEL: # BB#0: 432; ISEL-NEXT: andi. 3, 3, 1 433; ISEL-NEXT: li 4, 421 434; ISEL-NEXT: li 3, 42 435; ISEL-NEXT: isel 3, 4, 3, 1 436; ISEL-NEXT: blr 437; 438; NO_ISEL-LABEL: select_C1_C2_zeroext: 439; NO_ISEL: # BB#0: 440; NO_ISEL-NEXT: andi. 3, 3, 1 441; NO_ISEL-NEXT: li 4, 421 442; NO_ISEL-NEXT: li 3, 42 443; NO_ISEL-NEXT: bc 12, 1, .LBB19_1 444; NO_ISEL-NEXT: blr 445; NO_ISEL-NEXT: .LBB19_1: 446; NO_ISEL-NEXT: addi 3, 4, 0 447; NO_ISEL-NEXT: blr 448 %sel = select i1 %cond, i32 421, i32 42 449 ret i32 %sel 450} 451 452define i32 @select_C1_C2_signext(i1 signext %cond) { 453; ISEL-LABEL: select_C1_C2_signext: 454; ISEL: # BB#0: 455; ISEL-NEXT: andi. 3, 3, 1 456; ISEL-NEXT: li 4, 421 457; ISEL-NEXT: li 3, 42 458; ISEL-NEXT: isel 3, 4, 3, 1 459; ISEL-NEXT: blr 460; 461; NO_ISEL-LABEL: select_C1_C2_signext: 462; NO_ISEL: # BB#0: 463; NO_ISEL-NEXT: andi. 3, 3, 1 464; NO_ISEL-NEXT: li 4, 421 465; NO_ISEL-NEXT: li 3, 42 466; NO_ISEL-NEXT: bc 12, 1, .LBB20_1 467; NO_ISEL-NEXT: blr 468; NO_ISEL-NEXT: .LBB20_1: 469; NO_ISEL-NEXT: addi 3, 4, 0 470; NO_ISEL-NEXT: blr 471 %sel = select i1 %cond, i32 421, i32 42 472 ret i32 %sel 473} 474 475