1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm-eabi-unknown-unknown | FileCheck %s --check-prefix=ARM 3; RUN: llc < %s -mtriple=thumbv6t2-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB2 4; RUN: llc < %s -mtriple=thumb-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB 5 6; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?). 7; Test the zeroext/signext variants of each pattern to see if that makes a difference. 8 9; select Cond, 0, 1 --> zext (!Cond) 10 11define i32 @select_0_or_1(i1 %cond) { 12; ARM-LABEL: select_0_or_1: 13; ARM: @ %bb.0: 14; ARM-NEXT: mov r1, #1 15; ARM-NEXT: bic r0, r1, r0 16; ARM-NEXT: mov pc, lr 17; 18; THUMB2-LABEL: select_0_or_1: 19; THUMB2: @ %bb.0: 20; THUMB2-NEXT: movs r1, #1 21; THUMB2-NEXT: bic.w r0, r1, r0 22; THUMB2-NEXT: bx lr 23; 24; THUMB-LABEL: select_0_or_1: 25; THUMB: @ %bb.0: 26; THUMB-NEXT: movs r1, #1 27; THUMB-NEXT: bics r1, r0 28; THUMB-NEXT: movs r0, r1 29; THUMB-NEXT: bx lr 30 %sel = select i1 %cond, i32 0, i32 1 31 ret i32 %sel 32} 33 34define i32 @select_0_or_1_zeroext(i1 zeroext %cond) { 35; ARM-LABEL: select_0_or_1_zeroext: 36; ARM: @ %bb.0: 37; ARM-NEXT: eor r0, r0, #1 38; ARM-NEXT: mov pc, lr 39; 40; THUMB2-LABEL: select_0_or_1_zeroext: 41; THUMB2: @ %bb.0: 42; THUMB2-NEXT: eor r0, r0, #1 43; THUMB2-NEXT: bx lr 44; 45; THUMB-LABEL: select_0_or_1_zeroext: 46; THUMB: @ %bb.0: 47; THUMB-NEXT: movs r1, #1 48; THUMB-NEXT: eors r0, r1 49; THUMB-NEXT: bx lr 50 %sel = select i1 %cond, i32 0, i32 1 51 ret i32 %sel 52} 53 54define i32 @select_0_or_1_signext(i1 signext %cond) { 55; ARM-LABEL: select_0_or_1_signext: 56; ARM: @ %bb.0: 57; ARM-NEXT: mov r1, #1 58; ARM-NEXT: bic r0, r1, r0 59; ARM-NEXT: mov pc, lr 60; 61; THUMB2-LABEL: select_0_or_1_signext: 62; THUMB2: @ %bb.0: 63; THUMB2-NEXT: movs r1, #1 64; THUMB2-NEXT: bic.w r0, r1, r0 65; THUMB2-NEXT: bx lr 66; 67; THUMB-LABEL: select_0_or_1_signext: 68; THUMB: @ %bb.0: 69; THUMB-NEXT: movs r1, #1 70; THUMB-NEXT: bics r1, r0 71; THUMB-NEXT: movs r0, r1 72; THUMB-NEXT: bx lr 73 %sel = select i1 %cond, i32 0, i32 1 74 ret i32 %sel 75} 76 77; select Cond, 1, 0 --> zext (Cond) 78 79define i32 @select_1_or_0(i1 %cond) { 80; ARM-LABEL: select_1_or_0: 81; ARM: @ %bb.0: 82; ARM-NEXT: and r0, r0, #1 83; ARM-NEXT: mov pc, lr 84; 85; THUMB2-LABEL: select_1_or_0: 86; THUMB2: @ %bb.0: 87; THUMB2-NEXT: and r0, r0, #1 88; THUMB2-NEXT: bx lr 89; 90; THUMB-LABEL: select_1_or_0: 91; THUMB: @ %bb.0: 92; THUMB-NEXT: movs r1, #1 93; THUMB-NEXT: ands r0, r1 94; THUMB-NEXT: bx lr 95 %sel = select i1 %cond, i32 1, i32 0 96 ret i32 %sel 97} 98 99define i32 @select_1_or_0_zeroext(i1 zeroext %cond) { 100; ARM-LABEL: select_1_or_0_zeroext: 101; ARM: @ %bb.0: 102; ARM-NEXT: mov pc, lr 103; 104; THUMB2-LABEL: select_1_or_0_zeroext: 105; THUMB2: @ %bb.0: 106; THUMB2-NEXT: bx lr 107; 108; THUMB-LABEL: select_1_or_0_zeroext: 109; THUMB: @ %bb.0: 110; THUMB-NEXT: bx lr 111 %sel = select i1 %cond, i32 1, i32 0 112 ret i32 %sel 113} 114 115define i32 @select_1_or_0_signext(i1 signext %cond) { 116; ARM-LABEL: select_1_or_0_signext: 117; ARM: @ %bb.0: 118; ARM-NEXT: and r0, r0, #1 119; ARM-NEXT: mov pc, lr 120; 121; THUMB2-LABEL: select_1_or_0_signext: 122; THUMB2: @ %bb.0: 123; THUMB2-NEXT: and r0, r0, #1 124; THUMB2-NEXT: bx lr 125; 126; THUMB-LABEL: select_1_or_0_signext: 127; THUMB: @ %bb.0: 128; THUMB-NEXT: movs r1, #1 129; THUMB-NEXT: ands r0, r1 130; THUMB-NEXT: bx lr 131 %sel = select i1 %cond, i32 1, i32 0 132 ret i32 %sel 133} 134 135; select Cond, 0, -1 --> sext (!Cond) 136 137define i32 @select_0_or_neg1(i1 %cond) { 138; ARM-LABEL: select_0_or_neg1: 139; ARM: @ %bb.0: 140; ARM-NEXT: mov r1, #1 141; ARM-NEXT: bic r0, r1, r0 142; ARM-NEXT: rsb r0, r0, #0 143; ARM-NEXT: mov pc, lr 144; 145; THUMB2-LABEL: select_0_or_neg1: 146; THUMB2: @ %bb.0: 147; THUMB2-NEXT: movs r1, #1 148; THUMB2-NEXT: bic.w r0, r1, r0 149; THUMB2-NEXT: rsbs r0, r0, #0 150; THUMB2-NEXT: bx lr 151; 152; THUMB-LABEL: select_0_or_neg1: 153; THUMB: @ %bb.0: 154; THUMB-NEXT: movs r1, #1 155; THUMB-NEXT: bics r1, r0 156; THUMB-NEXT: rsbs r0, r1, #0 157; THUMB-NEXT: bx lr 158 %sel = select i1 %cond, i32 0, i32 -1 159 ret i32 %sel 160} 161 162define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) { 163; ARM-LABEL: select_0_or_neg1_zeroext: 164; ARM: @ %bb.0: 165; ARM-NEXT: eor r0, r0, #1 166; ARM-NEXT: rsb r0, r0, #0 167; ARM-NEXT: mov pc, lr 168; 169; THUMB2-LABEL: select_0_or_neg1_zeroext: 170; THUMB2: @ %bb.0: 171; THUMB2-NEXT: eor r0, r0, #1 172; THUMB2-NEXT: rsbs r0, r0, #0 173; THUMB2-NEXT: bx lr 174; 175; THUMB-LABEL: select_0_or_neg1_zeroext: 176; THUMB: @ %bb.0: 177; THUMB-NEXT: movs r1, #1 178; THUMB-NEXT: eors r1, r0 179; THUMB-NEXT: rsbs r0, r1, #0 180; THUMB-NEXT: bx lr 181 %sel = select i1 %cond, i32 0, i32 -1 182 ret i32 %sel 183} 184 185define i32 @select_0_or_neg1_signext(i1 signext %cond) { 186; ARM-LABEL: select_0_or_neg1_signext: 187; ARM: @ %bb.0: 188; ARM-NEXT: mvn r0, r0 189; ARM-NEXT: mov pc, lr 190; 191; THUMB2-LABEL: select_0_or_neg1_signext: 192; THUMB2: @ %bb.0: 193; THUMB2-NEXT: mvns r0, r0 194; THUMB2-NEXT: bx lr 195; 196; THUMB-LABEL: select_0_or_neg1_signext: 197; THUMB: @ %bb.0: 198; THUMB-NEXT: mvns r0, r0 199; THUMB-NEXT: bx lr 200 %sel = select i1 %cond, i32 0, i32 -1 201 ret i32 %sel 202} 203 204define i32 @select_0_or_neg1_alt(i1 %cond) { 205; ARM-LABEL: select_0_or_neg1_alt: 206; ARM: @ %bb.0: 207; ARM-NEXT: and r0, r0, #1 208; ARM-NEXT: sub r0, r0, #1 209; ARM-NEXT: mov pc, lr 210; 211; THUMB2-LABEL: select_0_or_neg1_alt: 212; THUMB2: @ %bb.0: 213; THUMB2-NEXT: and r0, r0, #1 214; THUMB2-NEXT: subs r0, #1 215; THUMB2-NEXT: bx lr 216; 217; THUMB-LABEL: select_0_or_neg1_alt: 218; THUMB: @ %bb.0: 219; THUMB-NEXT: movs r1, #1 220; THUMB-NEXT: ands r1, r0 221; THUMB-NEXT: subs r0, r1, #1 222; THUMB-NEXT: bx lr 223 %z = zext i1 %cond to i32 224 %add = add i32 %z, -1 225 ret i32 %add 226} 227 228define i32 @select_0_or_neg1_alt_zeroext(i1 zeroext %cond) { 229; ARM-LABEL: select_0_or_neg1_alt_zeroext: 230; ARM: @ %bb.0: 231; ARM-NEXT: sub r0, r0, #1 232; ARM-NEXT: mov pc, lr 233; 234; THUMB2-LABEL: select_0_or_neg1_alt_zeroext: 235; THUMB2: @ %bb.0: 236; THUMB2-NEXT: subs r0, #1 237; THUMB2-NEXT: bx lr 238; 239; THUMB-LABEL: select_0_or_neg1_alt_zeroext: 240; THUMB: @ %bb.0: 241; THUMB-NEXT: subs r0, r0, #1 242; THUMB-NEXT: bx lr 243 %z = zext i1 %cond to i32 244 %add = add i32 %z, -1 245 ret i32 %add 246} 247 248define i32 @select_0_or_neg1_alt_signext(i1 signext %cond) { 249; ARM-LABEL: select_0_or_neg1_alt_signext: 250; ARM: @ %bb.0: 251; ARM-NEXT: mvn r0, r0 252; ARM-NEXT: mov pc, lr 253; 254; THUMB2-LABEL: select_0_or_neg1_alt_signext: 255; THUMB2: @ %bb.0: 256; THUMB2-NEXT: mvns r0, r0 257; THUMB2-NEXT: bx lr 258; 259; THUMB-LABEL: select_0_or_neg1_alt_signext: 260; THUMB: @ %bb.0: 261; THUMB-NEXT: mvns r0, r0 262; THUMB-NEXT: bx lr 263 %z = zext i1 %cond to i32 264 %add = add i32 %z, -1 265 ret i32 %add 266} 267 268; select Cond, -1, 0 --> sext (Cond) 269 270define i32 @select_neg1_or_0(i1 %cond) { 271; ARM-LABEL: select_neg1_or_0: 272; ARM: @ %bb.0: 273; ARM-NEXT: and r0, r0, #1 274; ARM-NEXT: rsb r0, r0, #0 275; ARM-NEXT: mov pc, lr 276; 277; THUMB2-LABEL: select_neg1_or_0: 278; THUMB2: @ %bb.0: 279; THUMB2-NEXT: and r0, r0, #1 280; THUMB2-NEXT: rsbs r0, r0, #0 281; THUMB2-NEXT: bx lr 282; 283; THUMB-LABEL: select_neg1_or_0: 284; THUMB: @ %bb.0: 285; THUMB-NEXT: movs r1, #1 286; THUMB-NEXT: ands r1, r0 287; THUMB-NEXT: rsbs r0, r1, #0 288; THUMB-NEXT: bx lr 289 %sel = select i1 %cond, i32 -1, i32 0 290 ret i32 %sel 291} 292 293define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) { 294; ARM-LABEL: select_neg1_or_0_zeroext: 295; ARM: @ %bb.0: 296; ARM-NEXT: rsb r0, r0, #0 297; ARM-NEXT: mov pc, lr 298; 299; THUMB2-LABEL: select_neg1_or_0_zeroext: 300; THUMB2: @ %bb.0: 301; THUMB2-NEXT: rsbs r0, r0, #0 302; THUMB2-NEXT: bx lr 303; 304; THUMB-LABEL: select_neg1_or_0_zeroext: 305; THUMB: @ %bb.0: 306; THUMB-NEXT: rsbs r0, r0, #0 307; THUMB-NEXT: bx lr 308 %sel = select i1 %cond, i32 -1, i32 0 309 ret i32 %sel 310} 311 312define i32 @select_neg1_or_0_signext(i1 signext %cond) { 313; ARM-LABEL: select_neg1_or_0_signext: 314; ARM: @ %bb.0: 315; ARM-NEXT: mov pc, lr 316; 317; THUMB2-LABEL: select_neg1_or_0_signext: 318; THUMB2: @ %bb.0: 319; THUMB2-NEXT: bx lr 320; 321; THUMB-LABEL: select_neg1_or_0_signext: 322; THUMB: @ %bb.0: 323; THUMB-NEXT: bx lr 324 %sel = select i1 %cond, i32 -1, i32 0 325 ret i32 %sel 326} 327 328; select Cond, C+1, C --> add (zext Cond), C 329 330define i32 @select_Cplus1_C(i1 %cond) { 331; ARM-LABEL: select_Cplus1_C: 332; ARM: @ %bb.0: 333; ARM-NEXT: mov r1, #41 334; ARM-NEXT: tst r0, #1 335; ARM-NEXT: movne r1, #42 336; ARM-NEXT: mov r0, r1 337; ARM-NEXT: mov pc, lr 338; 339; THUMB2-LABEL: select_Cplus1_C: 340; THUMB2: @ %bb.0: 341; THUMB2-NEXT: lsls r0, r0, #31 342; THUMB2-NEXT: mov.w r0, #41 343; THUMB2-NEXT: it ne 344; THUMB2-NEXT: movne r0, #42 345; THUMB2-NEXT: bx lr 346; 347; THUMB-LABEL: select_Cplus1_C: 348; THUMB: @ %bb.0: 349; THUMB-NEXT: lsls r0, r0, #31 350; THUMB-NEXT: bne .LBB15_2 351; THUMB-NEXT: @ %bb.1: 352; THUMB-NEXT: movs r0, #41 353; THUMB-NEXT: bx lr 354; THUMB-NEXT: .LBB15_2: 355; THUMB-NEXT: movs r0, #42 356; THUMB-NEXT: bx lr 357 %sel = select i1 %cond, i32 42, i32 41 358 ret i32 %sel 359} 360 361define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) { 362; ARM-LABEL: select_Cplus1_C_zeroext: 363; ARM: @ %bb.0: 364; ARM-NEXT: mov r1, #41 365; ARM-NEXT: cmp r0, #0 366; ARM-NEXT: movne r1, #42 367; ARM-NEXT: mov r0, r1 368; ARM-NEXT: mov pc, lr 369; 370; THUMB2-LABEL: select_Cplus1_C_zeroext: 371; THUMB2: @ %bb.0: 372; THUMB2-NEXT: movs r1, #41 373; THUMB2-NEXT: cmp r0, #0 374; THUMB2-NEXT: it ne 375; THUMB2-NEXT: movne r1, #42 376; THUMB2-NEXT: mov r0, r1 377; THUMB2-NEXT: bx lr 378; 379; THUMB-LABEL: select_Cplus1_C_zeroext: 380; THUMB: @ %bb.0: 381; THUMB-NEXT: cmp r0, #0 382; THUMB-NEXT: bne .LBB16_2 383; THUMB-NEXT: @ %bb.1: 384; THUMB-NEXT: movs r0, #41 385; THUMB-NEXT: bx lr 386; THUMB-NEXT: .LBB16_2: 387; THUMB-NEXT: movs r0, #42 388; THUMB-NEXT: bx lr 389 %sel = select i1 %cond, i32 42, i32 41 390 ret i32 %sel 391} 392 393define i32 @select_Cplus1_C_signext(i1 signext %cond) { 394; ARM-LABEL: select_Cplus1_C_signext: 395; ARM: @ %bb.0: 396; ARM-NEXT: mov r1, #41 397; ARM-NEXT: tst r0, #1 398; ARM-NEXT: movne r1, #42 399; ARM-NEXT: mov r0, r1 400; ARM-NEXT: mov pc, lr 401; 402; THUMB2-LABEL: select_Cplus1_C_signext: 403; THUMB2: @ %bb.0: 404; THUMB2-NEXT: lsls r0, r0, #31 405; THUMB2-NEXT: mov.w r0, #41 406; THUMB2-NEXT: it ne 407; THUMB2-NEXT: movne r0, #42 408; THUMB2-NEXT: bx lr 409; 410; THUMB-LABEL: select_Cplus1_C_signext: 411; THUMB: @ %bb.0: 412; THUMB-NEXT: lsls r0, r0, #31 413; THUMB-NEXT: bne .LBB17_2 414; THUMB-NEXT: @ %bb.1: 415; THUMB-NEXT: movs r0, #41 416; THUMB-NEXT: bx lr 417; THUMB-NEXT: .LBB17_2: 418; THUMB-NEXT: movs r0, #42 419; THUMB-NEXT: bx lr 420 %sel = select i1 %cond, i32 42, i32 41 421 ret i32 %sel 422} 423 424; select Cond, C, C+1 --> add (sext Cond), C 425 426define i32 @select_C_Cplus1(i1 %cond) { 427; ARM-LABEL: select_C_Cplus1: 428; ARM: @ %bb.0: 429; ARM-NEXT: mov r1, #42 430; ARM-NEXT: tst r0, #1 431; ARM-NEXT: movne r1, #41 432; ARM-NEXT: mov r0, r1 433; ARM-NEXT: mov pc, lr 434; 435; THUMB2-LABEL: select_C_Cplus1: 436; THUMB2: @ %bb.0: 437; THUMB2-NEXT: lsls r0, r0, #31 438; THUMB2-NEXT: mov.w r0, #42 439; THUMB2-NEXT: it ne 440; THUMB2-NEXT: movne r0, #41 441; THUMB2-NEXT: bx lr 442; 443; THUMB-LABEL: select_C_Cplus1: 444; THUMB: @ %bb.0: 445; THUMB-NEXT: lsls r0, r0, #31 446; THUMB-NEXT: bne .LBB18_2 447; THUMB-NEXT: @ %bb.1: 448; THUMB-NEXT: movs r0, #42 449; THUMB-NEXT: bx lr 450; THUMB-NEXT: .LBB18_2: 451; THUMB-NEXT: movs r0, #41 452; THUMB-NEXT: bx lr 453 %sel = select i1 %cond, i32 41, i32 42 454 ret i32 %sel 455} 456 457define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) { 458; ARM-LABEL: select_C_Cplus1_zeroext: 459; ARM: @ %bb.0: 460; ARM-NEXT: mov r1, #42 461; ARM-NEXT: cmp r0, #0 462; ARM-NEXT: movne r1, #41 463; ARM-NEXT: mov r0, r1 464; ARM-NEXT: mov pc, lr 465; 466; THUMB2-LABEL: select_C_Cplus1_zeroext: 467; THUMB2: @ %bb.0: 468; THUMB2-NEXT: movs r1, #42 469; THUMB2-NEXT: cmp r0, #0 470; THUMB2-NEXT: it ne 471; THUMB2-NEXT: movne r1, #41 472; THUMB2-NEXT: mov r0, r1 473; THUMB2-NEXT: bx lr 474; 475; THUMB-LABEL: select_C_Cplus1_zeroext: 476; THUMB: @ %bb.0: 477; THUMB-NEXT: cmp r0, #0 478; THUMB-NEXT: bne .LBB19_2 479; THUMB-NEXT: @ %bb.1: 480; THUMB-NEXT: movs r0, #42 481; THUMB-NEXT: bx lr 482; THUMB-NEXT: .LBB19_2: 483; THUMB-NEXT: movs r0, #41 484; THUMB-NEXT: bx lr 485 %sel = select i1 %cond, i32 41, i32 42 486 ret i32 %sel 487} 488 489define i32 @select_C_Cplus1_signext(i1 signext %cond) { 490; ARM-LABEL: select_C_Cplus1_signext: 491; ARM: @ %bb.0: 492; ARM-NEXT: mov r1, #42 493; ARM-NEXT: tst r0, #1 494; ARM-NEXT: movne r1, #41 495; ARM-NEXT: mov r0, r1 496; ARM-NEXT: mov pc, lr 497; 498; THUMB2-LABEL: select_C_Cplus1_signext: 499; THUMB2: @ %bb.0: 500; THUMB2-NEXT: lsls r0, r0, #31 501; THUMB2-NEXT: mov.w r0, #42 502; THUMB2-NEXT: it ne 503; THUMB2-NEXT: movne r0, #41 504; THUMB2-NEXT: bx lr 505; 506; THUMB-LABEL: select_C_Cplus1_signext: 507; THUMB: @ %bb.0: 508; THUMB-NEXT: lsls r0, r0, #31 509; THUMB-NEXT: bne .LBB20_2 510; THUMB-NEXT: @ %bb.1: 511; THUMB-NEXT: movs r0, #42 512; THUMB-NEXT: bx lr 513; THUMB-NEXT: .LBB20_2: 514; THUMB-NEXT: movs r0, #41 515; THUMB-NEXT: bx lr 516 %sel = select i1 %cond, i32 41, i32 42 517 ret i32 %sel 518} 519 520; In general, select of 2 constants could be: 521; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2 522 523define i32 @select_C1_C2(i1 %cond) { 524; ARM-LABEL: select_C1_C2: 525; ARM: @ %bb.0: 526; ARM-NEXT: mov r1, #165 527; ARM-NEXT: tst r0, #1 528; ARM-NEXT: orr r1, r1, #256 529; ARM-NEXT: moveq r1, #42 530; ARM-NEXT: mov r0, r1 531; ARM-NEXT: mov pc, lr 532; 533; THUMB2-LABEL: select_C1_C2: 534; THUMB2: @ %bb.0: 535; THUMB2-NEXT: lsls r0, r0, #31 536; THUMB2-NEXT: mov.w r0, #42 537; THUMB2-NEXT: it ne 538; THUMB2-NEXT: movwne r0, #421 539; THUMB2-NEXT: bx lr 540; 541; THUMB-LABEL: select_C1_C2: 542; THUMB: @ %bb.0: 543; THUMB-NEXT: lsls r0, r0, #31 544; THUMB-NEXT: bne .LBB21_2 545; THUMB-NEXT: @ %bb.1: 546; THUMB-NEXT: movs r0, #42 547; THUMB-NEXT: bx lr 548; THUMB-NEXT: .LBB21_2: 549; THUMB-NEXT: movs r0, #255 550; THUMB-NEXT: adds r0, #166 551; THUMB-NEXT: bx lr 552 %sel = select i1 %cond, i32 421, i32 42 553 ret i32 %sel 554} 555 556define i32 @select_C1_C2_zeroext(i1 zeroext %cond) { 557; ARM-LABEL: select_C1_C2_zeroext: 558; ARM: @ %bb.0: 559; ARM-NEXT: mov r1, #165 560; ARM-NEXT: cmp r0, #0 561; ARM-NEXT: orr r1, r1, #256 562; ARM-NEXT: moveq r1, #42 563; ARM-NEXT: mov r0, r1 564; ARM-NEXT: mov pc, lr 565; 566; THUMB2-LABEL: select_C1_C2_zeroext: 567; THUMB2: @ %bb.0: 568; THUMB2-NEXT: movs r1, #42 569; THUMB2-NEXT: cmp r0, #0 570; THUMB2-NEXT: it ne 571; THUMB2-NEXT: movwne r1, #421 572; THUMB2-NEXT: mov r0, r1 573; THUMB2-NEXT: bx lr 574; 575; THUMB-LABEL: select_C1_C2_zeroext: 576; THUMB: @ %bb.0: 577; THUMB-NEXT: cmp r0, #0 578; THUMB-NEXT: bne .LBB22_2 579; THUMB-NEXT: @ %bb.1: 580; THUMB-NEXT: movs r0, #42 581; THUMB-NEXT: bx lr 582; THUMB-NEXT: .LBB22_2: 583; THUMB-NEXT: movs r0, #255 584; THUMB-NEXT: adds r0, #166 585; THUMB-NEXT: bx lr 586 %sel = select i1 %cond, i32 421, i32 42 587 ret i32 %sel 588} 589 590define i32 @select_C1_C2_signext(i1 signext %cond) { 591; ARM-LABEL: select_C1_C2_signext: 592; ARM: @ %bb.0: 593; ARM-NEXT: mov r1, #165 594; ARM-NEXT: tst r0, #1 595; ARM-NEXT: orr r1, r1, #256 596; ARM-NEXT: moveq r1, #42 597; ARM-NEXT: mov r0, r1 598; ARM-NEXT: mov pc, lr 599; 600; THUMB2-LABEL: select_C1_C2_signext: 601; THUMB2: @ %bb.0: 602; THUMB2-NEXT: lsls r0, r0, #31 603; THUMB2-NEXT: mov.w r0, #42 604; THUMB2-NEXT: it ne 605; THUMB2-NEXT: movwne r0, #421 606; THUMB2-NEXT: bx lr 607; 608; THUMB-LABEL: select_C1_C2_signext: 609; THUMB: @ %bb.0: 610; THUMB-NEXT: lsls r0, r0, #31 611; THUMB-NEXT: bne .LBB23_2 612; THUMB-NEXT: @ %bb.1: 613; THUMB-NEXT: movs r0, #42 614; THUMB-NEXT: bx lr 615; THUMB-NEXT: .LBB23_2: 616; THUMB-NEXT: movs r0, #255 617; THUMB-NEXT: adds r0, #166 618; THUMB-NEXT: bx lr 619 %sel = select i1 %cond, i32 421, i32 42 620 ret i32 %sel 621} 622 623; 4295032833 = 0x100010001. 624; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select. 625 626define i64 @opaque_constant1(i1 %cond, i64 %x) { 627; ARM-LABEL: opaque_constant1: 628; ARM: @ %bb.0: 629; ARM-NEXT: .save {r4, lr} 630; ARM-NEXT: push {r4, lr} 631; ARM-NEXT: mov lr, #1 632; ARM-NEXT: ands r12, r0, #1 633; ARM-NEXT: mov r0, #23 634; ARM-NEXT: orr lr, lr, #65536 635; ARM-NEXT: mvnne r0, #3 636; ARM-NEXT: and r4, r0, lr 637; ARM-NEXT: movne r12, #1 638; ARM-NEXT: subs r0, r4, #1 639; ARM-NEXT: eor r2, r2, lr 640; ARM-NEXT: eor r3, r3, #1 641; ARM-NEXT: sbc r1, r12, #0 642; ARM-NEXT: orrs r2, r2, r3 643; ARM-NEXT: movne r0, r4 644; ARM-NEXT: movne r1, r12 645; ARM-NEXT: pop {r4, lr} 646; ARM-NEXT: mov pc, lr 647; 648; THUMB2-LABEL: opaque_constant1: 649; THUMB2: @ %bb.0: 650; THUMB2-NEXT: .save {r7, lr} 651; THUMB2-NEXT: push {r7, lr} 652; THUMB2-NEXT: ands r12, r0, #1 653; THUMB2-NEXT: mov.w lr, #1 654; THUMB2-NEXT: itt ne 655; THUMB2-NEXT: movne.w lr, #65536 656; THUMB2-NEXT: movne.w r12, #1 657; THUMB2-NEXT: subs.w r0, lr, #1 658; THUMB2-NEXT: sbc r1, r12, #0 659; THUMB2-NEXT: eor r3, r3, #1 660; THUMB2-NEXT: eor r2, r2, #65537 661; THUMB2-NEXT: orrs r2, r3 662; THUMB2-NEXT: itt ne 663; THUMB2-NEXT: movne r0, lr 664; THUMB2-NEXT: movne r1, r12 665; THUMB2-NEXT: pop {r7, pc} 666; 667; THUMB-LABEL: opaque_constant1: 668; THUMB: @ %bb.0: 669; THUMB-NEXT: .save {r4, r5, r6, r7, lr} 670; THUMB-NEXT: push {r4, r5, r6, r7, lr} 671; THUMB-NEXT: movs r7, #1 672; THUMB-NEXT: ands r0, r7 673; THUMB-NEXT: subs r1, r0, #1 674; THUMB-NEXT: push {r0} 675; THUMB-NEXT: pop {r4} 676; THUMB-NEXT: sbcs r4, r1 677; THUMB-NEXT: cmp r0, #0 678; THUMB-NEXT: bne .LBB24_2 679; THUMB-NEXT: @ %bb.1: 680; THUMB-NEXT: movs r5, #23 681; THUMB-NEXT: b .LBB24_3 682; THUMB-NEXT: .LBB24_2: 683; THUMB-NEXT: movs r0, #3 684; THUMB-NEXT: mvns r5, r0 685; THUMB-NEXT: .LBB24_3: 686; THUMB-NEXT: ldr r0, .LCPI24_0 687; THUMB-NEXT: ands r5, r0 688; THUMB-NEXT: movs r6, #0 689; THUMB-NEXT: subs r0, r5, #1 690; THUMB-NEXT: push {r4} 691; THUMB-NEXT: pop {r1} 692; THUMB-NEXT: sbcs r1, r6 693; THUMB-NEXT: eors r3, r7 694; THUMB-NEXT: ldr r6, .LCPI24_0 695; THUMB-NEXT: eors r2, r6 696; THUMB-NEXT: orrs r2, r3 697; THUMB-NEXT: beq .LBB24_5 698; THUMB-NEXT: @ %bb.4: 699; THUMB-NEXT: movs r1, r4 700; THUMB-NEXT: .LBB24_5: 701; THUMB-NEXT: cmp r2, #0 702; THUMB-NEXT: beq .LBB24_7 703; THUMB-NEXT: @ %bb.6: 704; THUMB-NEXT: movs r0, r5 705; THUMB-NEXT: .LBB24_7: 706; THUMB-NEXT: pop {r4, r5, r6, r7} 707; THUMB-NEXT: pop {r2} 708; THUMB-NEXT: bx r2 709; THUMB-NEXT: .p2align 2 710; THUMB-NEXT: @ %bb.8: 711; THUMB-NEXT: .LCPI24_0: 712; THUMB-NEXT: .long 65537 @ 0x10001 713 %sel = select i1 %cond, i64 -4, i64 23 714 %bo = and i64 %sel, 4295032833 ; 0x100010001 715 %cmp = icmp eq i64 %x, 4295032833 716 %sext = sext i1 %cmp to i64 717 %add = add i64 %bo, %sext 718 ret i64 %add 719} 720 721; 65537 == 0x10001. 722; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select. 723 724define i64 @opaque_constant2(i1 %cond, i64 %x) { 725; ARM-LABEL: opaque_constant2: 726; ARM: @ %bb.0: 727; ARM-NEXT: mov r1, #1 728; ARM-NEXT: tst r0, #1 729; ARM-NEXT: orr r1, r1, #65536 730; ARM-NEXT: moveq r1, #23 731; ARM-NEXT: bic r0, r1, #22 732; ARM-NEXT: mov r1, #0 733; ARM-NEXT: mov pc, lr 734; 735; THUMB2-LABEL: opaque_constant2: 736; THUMB2: @ %bb.0: 737; THUMB2-NEXT: lsls r0, r0, #31 738; THUMB2-NEXT: mov.w r1, #0 739; THUMB2-NEXT: mov.w r0, #1 740; THUMB2-NEXT: it ne 741; THUMB2-NEXT: movne.w r0, #65537 742; THUMB2-NEXT: bx lr 743; 744; THUMB-LABEL: opaque_constant2: 745; THUMB: @ %bb.0: 746; THUMB-NEXT: lsls r0, r0, #31 747; THUMB-NEXT: bne .LBB25_2 748; THUMB-NEXT: @ %bb.1: 749; THUMB-NEXT: movs r0, #23 750; THUMB-NEXT: b .LBB25_3 751; THUMB-NEXT: .LBB25_2: 752; THUMB-NEXT: ldr r0, .LCPI25_0 753; THUMB-NEXT: .LBB25_3: 754; THUMB-NEXT: movs r1, #22 755; THUMB-NEXT: bics r0, r1 756; THUMB-NEXT: movs r1, #0 757; THUMB-NEXT: bx lr 758; THUMB-NEXT: .p2align 2 759; THUMB-NEXT: @ %bb.4: 760; THUMB-NEXT: .LCPI25_0: 761; THUMB-NEXT: .long 65537 @ 0x10001 762 %sel = select i1 %cond, i64 65537, i64 23 763 %bo = and i64 %sel, 65537 764 ret i64 %bo 765} 766 767