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