1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm-- -mcpu=cortex-a8 | FileCheck %s -check-prefixes=CHECK,ARM 3; RUN: llc < %s -mtriple=thumb-- -mcpu=cortex-a8 | FileCheck %s -check-prefixes=CHECK,T2 4; rdar://8662825 5 6define i32 @t1(i32 %a, i32 %b, i32 %c) nounwind { 7; ARM-LABEL: t1: 8; ARM: @ %bb.0: 9; ARM-NEXT: mov r0, r1 10; ARM-NEXT: cmp r2, #10 11; ARM-NEXT: suble r0, r0, #-2147483647 12; ARM-NEXT: bx lr 13; 14; T2-LABEL: t1: 15; T2: @ %bb.0: 16; T2-NEXT: mov r0, r1 17; T2-NEXT: mvn r1, #-2147483648 18; T2-NEXT: cmp r2, #10 19; T2-NEXT: it le 20; T2-NEXT: addle r0, r1 21; T2-NEXT: bx lr 22 %tmp1 = icmp sgt i32 %c, 10 23 %tmp2 = select i1 %tmp1, i32 0, i32 2147483647 24 %tmp3 = add i32 %tmp2, %b 25 ret i32 %tmp3 26} 27 28define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 29; ARM-LABEL: t2: 30; ARM: @ %bb.0: 31; ARM-NEXT: mov r0, r1 32; ARM-NEXT: cmp r2, #10 33; ARM-NEXT: suble r0, r0, #10 34; ARM-NEXT: bx lr 35; 36; T2-LABEL: t2: 37; T2: @ %bb.0: 38; T2-NEXT: mov r0, r1 39; T2-NEXT: cmp r2, #10 40; T2-NEXT: it le 41; T2-NEXT: suble r0, #10 42; T2-NEXT: bx lr 43 %tmp1 = icmp sgt i32 %c, 10 44 %tmp2 = select i1 %tmp1, i32 0, i32 10 45 %tmp3 = sub i32 %b, %tmp2 46 ret i32 %tmp3 47} 48 49define i32 @t3(i32 %a, i32 %b, i32 %x, i32 %y) nounwind { 50; ARM-LABEL: t3: 51; ARM: @ %bb.0: 52; ARM-NEXT: cmp r0, r1 53; ARM-NEXT: andge r3, r3, r2 54; ARM-NEXT: mov r0, r3 55; ARM-NEXT: bx lr 56; 57; T2-LABEL: t3: 58; T2: @ %bb.0: 59; T2-NEXT: cmp r0, r1 60; T2-NEXT: it ge 61; T2-NEXT: andge r3, r2 62; T2-NEXT: mov r0, r3 63; T2-NEXT: bx lr 64 %cond = icmp slt i32 %a, %b 65 %z = select i1 %cond, i32 -1, i32 %x 66 %s = and i32 %z, %y 67 ret i32 %s 68} 69 70define i32 @t4(i32 %a, i32 %b, i32 %x, i32 %y) nounwind { 71; ARM-LABEL: t4: 72; ARM: @ %bb.0: 73; ARM-NEXT: cmp r0, r1 74; ARM-NEXT: orrge r3, r3, r2 75; ARM-NEXT: mov r0, r3 76; ARM-NEXT: bx lr 77; 78; T2-LABEL: t4: 79; T2: @ %bb.0: 80; T2-NEXT: cmp r0, r1 81; T2-NEXT: it ge 82; T2-NEXT: orrge r3, r2 83; T2-NEXT: mov r0, r3 84; T2-NEXT: bx lr 85 %cond = icmp slt i32 %a, %b 86 %z = select i1 %cond, i32 0, i32 %x 87 %s = or i32 %z, %y 88 ret i32 %s 89} 90 91define i32 @t5(i32 %a, i32 %b, i32 %c) nounwind { 92; ARM-LABEL: t5: 93; ARM: @ %bb.0: @ %entry 94; ARM-NEXT: cmp r0, r1 95; ARM-NEXT: orreq r2, r2, #1 96; ARM-NEXT: mov r0, r2 97; ARM-NEXT: bx lr 98; 99; T2-LABEL: t5: 100; T2: @ %bb.0: @ %entry 101; T2-NEXT: cmp r0, r1 102; T2-NEXT: it eq 103; T2-NEXT: orreq r2, r2, #1 104; T2-NEXT: mov r0, r2 105; T2-NEXT: bx lr 106entry: 107 %tmp1 = icmp eq i32 %a, %b 108 %tmp2 = zext i1 %tmp1 to i32 109 %tmp3 = or i32 %tmp2, %c 110 ret i32 %tmp3 111} 112 113define i32 @t6(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 114; ARM-LABEL: t6: 115; ARM: @ %bb.0: 116; ARM-NEXT: cmp r0, r1 117; ARM-NEXT: eorlt r3, r3, r2 118; ARM-NEXT: mov r0, r3 119; ARM-NEXT: bx lr 120; 121; T2-LABEL: t6: 122; T2: @ %bb.0: 123; T2-NEXT: cmp r0, r1 124; T2-NEXT: it lt 125; T2-NEXT: eorlt r3, r2 126; T2-NEXT: mov r0, r3 127; T2-NEXT: bx lr 128 %cond = icmp slt i32 %a, %b 129 %tmp1 = select i1 %cond, i32 %c, i32 0 130 %tmp2 = xor i32 %tmp1, %d 131 ret i32 %tmp2 132} 133 134define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind { 135; ARM-LABEL: t7: 136; ARM: @ %bb.0: @ %entry 137; ARM-NEXT: cmp r0, r1 138; ARM-NEXT: andeq r2, r2, r2, lsl #1 139; ARM-NEXT: mov r0, r2 140; ARM-NEXT: bx lr 141; 142; T2-LABEL: t7: 143; T2: @ %bb.0: @ %entry 144; T2-NEXT: cmp r0, r1 145; T2-NEXT: it eq 146; T2-NEXT: andeq.w r2, r2, r2, lsl #1 147; T2-NEXT: mov r0, r2 148; T2-NEXT: bx lr 149entry: 150 %tmp1 = shl i32 %c, 1 151 %cond = icmp eq i32 %a, %b 152 %tmp2 = select i1 %cond, i32 %tmp1, i32 -1 153 %tmp3 = and i32 %c, %tmp2 154 ret i32 %tmp3 155} 156 157; Fold ORRri into movcc. 158define i32 @t8(i32 %a, i32 %b) nounwind { 159; ARM-LABEL: t8: 160; ARM: @ %bb.0: 161; ARM-NEXT: cmp r0, r1 162; ARM-NEXT: orrge r0, r1, #1 163; ARM-NEXT: bx lr 164; 165; T2-LABEL: t8: 166; T2: @ %bb.0: 167; T2-NEXT: cmp r0, r1 168; T2-NEXT: it ge 169; T2-NEXT: orrge r0, r1, #1 170; T2-NEXT: bx lr 171 %x = or i32 %b, 1 172 %cond = icmp slt i32 %a, %b 173 %tmp1 = select i1 %cond, i32 %a, i32 %x 174 ret i32 %tmp1 175} 176 177; Fold ANDrr into movcc. 178define i32 @t9(i32 %a, i32 %b, i32 %c) nounwind { 179; ARM-LABEL: t9: 180; ARM: @ %bb.0: 181; ARM-NEXT: cmp r0, r1 182; ARM-NEXT: andge r0, r1, r2 183; ARM-NEXT: bx lr 184; 185; T2-LABEL: t9: 186; T2: @ %bb.0: 187; T2-NEXT: cmp r0, r1 188; T2-NEXT: it ge 189; T2-NEXT: andge.w r0, r1, r2 190; T2-NEXT: bx lr 191 %x = and i32 %b, %c 192 %cond = icmp slt i32 %a, %b 193 %tmp1 = select i1 %cond, i32 %a, i32 %x 194 ret i32 %tmp1 195} 196 197; Fold EORrs into movcc. 198define i32 @t10(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 199; ARM-LABEL: t10: 200; ARM: @ %bb.0: 201; ARM-NEXT: cmp r0, r1 202; ARM-NEXT: eorge r0, r1, r2, lsl #7 203; ARM-NEXT: bx lr 204; 205; T2-LABEL: t10: 206; T2: @ %bb.0: 207; T2-NEXT: cmp r0, r1 208; T2-NEXT: it ge 209; T2-NEXT: eorge.w r0, r1, r2, lsl #7 210; T2-NEXT: bx lr 211 %s = shl i32 %c, 7 212 %x = xor i32 %b, %s 213 %cond = icmp slt i32 %a, %b 214 %tmp1 = select i1 %cond, i32 %a, i32 %x 215 ret i32 %tmp1 216} 217 218; Fold ORRri into movcc, reversing the condition. 219define i32 @t11(i32 %a, i32 %b) nounwind { 220; ARM-LABEL: t11: 221; ARM: @ %bb.0: 222; ARM-NEXT: cmp r0, r1 223; ARM-NEXT: orrlt r0, r1, #1 224; ARM-NEXT: bx lr 225; 226; T2-LABEL: t11: 227; T2: @ %bb.0: 228; T2-NEXT: cmp r0, r1 229; T2-NEXT: it lt 230; T2-NEXT: orrlt r0, r1, #1 231; T2-NEXT: bx lr 232 %x = or i32 %b, 1 233 %cond = icmp slt i32 %a, %b 234 %tmp1 = select i1 %cond, i32 %x, i32 %a 235 ret i32 %tmp1 236} 237 238; Fold ADDri12 into movcc 239define i32 @t12(i32 %a, i32 %b) nounwind { 240; ARM-LABEL: t12: 241; ARM: @ %bb.0: 242; ARM-NEXT: cmp r0, r1 243; ARM-NEXT: movw r2, #3000 244; ARM-NEXT: addge r0, r1, r2 245; ARM-NEXT: bx lr 246; 247; T2-LABEL: t12: 248; T2: @ %bb.0: 249; T2-NEXT: cmp r0, r1 250; T2-NEXT: it ge 251; T2-NEXT: addwge r0, r1, #3000 252; T2-NEXT: bx lr 253 %x = add i32 %b, 3000 254 %cond = icmp slt i32 %a, %b 255 %tmp1 = select i1 %cond, i32 %a, i32 %x 256 ret i32 %tmp1 257} 258 259; Handle frame index operands. 260define void @pr13628() nounwind uwtable align 2 { 261; ARM-LABEL: pr13628: 262; ARM: @ %bb.0: 263; ARM-NEXT: push {r11, lr} 264; ARM-NEXT: sub sp, sp, #256 265; ARM-NEXT: ldrb r1, [r0] 266; ARM-NEXT: mov r0, sp 267; ARM-NEXT: cmp r1, #0 268; ARM-NEXT: moveq r0, r1 269; ARM-NEXT: bl bar 270; ARM-NEXT: add sp, sp, #256 271; ARM-NEXT: pop {r11, pc} 272; 273; T2-LABEL: pr13628: 274; T2: @ %bb.0: 275; T2-NEXT: push {r7, lr} 276; T2-NEXT: sub sp, #256 277; T2-NEXT: ldrb r1, [r0] 278; T2-NEXT: mov r0, sp 279; T2-NEXT: cmp r1, #0 280; T2-NEXT: it eq 281; T2-NEXT: moveq r0, r1 282; T2-NEXT: bl bar 283; T2-NEXT: add sp, #256 284; T2-NEXT: pop {r7, pc} 285 %x3 = alloca i8, i32 256, align 8 286 %x4 = load i8, ptr undef, align 1 287 %x5 = icmp ne i8 %x4, 0 288 %x6 = select i1 %x5, ptr %x3, ptr null 289 call void @bar(ptr %x6) nounwind 290 ret void 291} 292declare void @bar(ptr) 293 294; Fold zext i1 into predicated add 295define i32 @t13(i32 %c, i32 %a) nounwind readnone ssp { 296; ARM-LABEL: t13: 297; ARM: @ %bb.0: @ %entry 298; ARM-NEXT: cmp r1, #10 299; ARM-NEXT: addgt r0, r0, #1 300; ARM-NEXT: bx lr 301; 302; T2-LABEL: t13: 303; T2: @ %bb.0: @ %entry 304; T2-NEXT: cmp r1, #10 305; T2-NEXT: it gt 306; T2-NEXT: addgt r0, #1 307; T2-NEXT: bx lr 308entry: 309 %cmp = icmp sgt i32 %a, 10 310 %conv = zext i1 %cmp to i32 311 %add = add i32 %conv, %c 312 ret i32 %add 313} 314 315; Fold sext i1 into predicated sub 316define i32 @t14(i32 %c, i32 %a) nounwind readnone ssp { 317; ARM-LABEL: t14: 318; ARM: @ %bb.0: @ %entry 319; ARM-NEXT: cmp r1, #10 320; ARM-NEXT: subgt r0, r0, #1 321; ARM-NEXT: bx lr 322; 323; T2-LABEL: t14: 324; T2: @ %bb.0: @ %entry 325; T2-NEXT: cmp r1, #10 326; T2-NEXT: it gt 327; T2-NEXT: subgt r0, #1 328; T2-NEXT: bx lr 329entry: 330 %cmp = icmp sgt i32 %a, 10 331 %conv = sext i1 %cmp to i32 332 %add = add i32 %conv, %c 333 ret i32 %add 334} 335 336; Fold the xor into the select. 337define i32 @t15(i32 %p) { 338; ARM-LABEL: t15: 339; ARM: @ %bb.0: @ %entry 340; ARM-NEXT: mov r1, #3 341; ARM-NEXT: cmp r0, #8 342; ARM-NEXT: movwgt r1, #0 343; ARM-NEXT: mov r0, r1 344; ARM-NEXT: bx lr 345; 346; T2-LABEL: t15: 347; T2: @ %bb.0: @ %entry 348; T2-NEXT: movs r1, #3 349; T2-NEXT: cmp r0, #8 350; T2-NEXT: it gt 351; T2-NEXT: movgt r1, #0 352; T2-NEXT: mov r0, r1 353; T2-NEXT: bx lr 354entry: 355 %cmp = icmp sgt i32 %p, 8 356 %a = select i1 %cmp, i32 1, i32 2 357 %xor = xor i32 %a, 1 358 ret i32 %xor 359} 360 361define i32 @t16(i32 %x, i32 %y) { 362; ARM-LABEL: t16: 363; ARM: @ %bb.0: @ %entry 364; ARM-NEXT: cmp r0, #0 365; ARM-NEXT: mov r2, #2 366; ARM-NEXT: movweq r2, #5 367; ARM-NEXT: mov r0, #4 368; ARM-NEXT: cmp r1, #0 369; ARM-NEXT: movweq r0, #3 370; ARM-NEXT: and r0, r0, r2 371; ARM-NEXT: bx lr 372; 373; T2-LABEL: t16: 374; T2: @ %bb.0: @ %entry 375; T2-NEXT: cmp r0, #0 376; T2-NEXT: mov.w r2, #2 377; T2-NEXT: mov.w r0, #4 378; T2-NEXT: it eq 379; T2-NEXT: moveq r2, #5 380; T2-NEXT: cmp r1, #0 381; T2-NEXT: it eq 382; T2-NEXT: moveq r0, #3 383; T2-NEXT: ands r0, r2 384; T2-NEXT: bx lr 385entry: 386 %cmp = icmp eq i32 %x, 0 387 %cond = select i1 %cmp, i32 5, i32 2 388 %cmp1 = icmp eq i32 %y, 0 389 %cond2 = select i1 %cmp1, i32 3, i32 4 390 %and = and i32 %cond2, %cond 391 ret i32 %and 392} 393 394define i32 @t17(i32 %x, i32 %y) #0 { 395; ARM-LABEL: t17: 396; ARM: @ %bb.0: @ %entry 397; ARM-NEXT: cmn r0, #1 398; ARM-NEXT: mov r2, #2 399; ARM-NEXT: movweq r2, #5 400; ARM-NEXT: mov r0, #4 401; ARM-NEXT: cmn r1, #1 402; ARM-NEXT: movweq r0, #3 403; ARM-NEXT: and r0, r0, r2 404; ARM-NEXT: bx lr 405; 406; T2-LABEL: t17: 407; T2: @ %bb.0: @ %entry 408; T2-NEXT: adds r0, #1 409; T2-NEXT: mov.w r0, #2 410; T2-NEXT: it eq 411; T2-NEXT: moveq r0, #5 412; T2-NEXT: adds r1, #1 413; T2-NEXT: mov.w r1, #4 414; T2-NEXT: it eq 415; T2-NEXT: moveq r1, #3 416; T2-NEXT: ands r0, r1 417; T2-NEXT: bx lr 418entry: 419 %cmp = icmp eq i32 %x, -1 420 %cond = select i1 %cmp, i32 5, i32 2 421 %cmp1 = icmp eq i32 %y, -1 422 %cond2 = select i1 %cmp1, i32 3, i32 4 423 %and = and i32 %cond2, %cond 424 ret i32 %and 425} 426 427define i32 @t18(i32 %x, i32 %y) #0 { 428; ARM-LABEL: t18: 429; ARM: @ %bb.0: @ %entry 430; ARM-NEXT: mov r1, #2 431; ARM-NEXT: cmp r0, #0 432; ARM-NEXT: movwne r1, #5 433; ARM-NEXT: mov r2, #4 434; ARM-NEXT: cmn r0, #1 435; ARM-NEXT: movwne r2, #3 436; ARM-NEXT: and r0, r2, r1 437; ARM-NEXT: bx lr 438; 439; T2-LABEL: t18: 440; T2: @ %bb.0: @ %entry 441; T2-NEXT: movs r1, #2 442; T2-NEXT: cmp r0, #0 443; T2-NEXT: it ne 444; T2-NEXT: movne r1, #5 445; T2-NEXT: adds r0, #1 446; T2-NEXT: mov.w r0, #4 447; T2-NEXT: it ne 448; T2-NEXT: movne r0, #3 449; T2-NEXT: ands r0, r1 450; T2-NEXT: bx lr 451entry: 452 %cmp = icmp ne i32 %x, 0 453 %cond = select i1 %cmp, i32 5, i32 2 454 %cmp1 = icmp ne i32 %x, -1 455 %cond2 = select i1 %cmp1, i32 3, i32 4 456 %and = and i32 %cond2, %cond 457 ret i32 %and 458} 459 460define i32 @t19(i32 %x, i32 %y) #0 { 461; ARM-LABEL: t19: 462; ARM: @ %bb.0: @ %entry 463; ARM-NEXT: cmp r0, #0 464; ARM-NEXT: mov r2, #2 465; ARM-NEXT: movwne r2, #5 466; ARM-NEXT: mov r0, #4 467; ARM-NEXT: cmp r1, #0 468; ARM-NEXT: movwne r0, #3 469; ARM-NEXT: orr r0, r0, r2 470; ARM-NEXT: bx lr 471; 472; T2-LABEL: t19: 473; T2: @ %bb.0: @ %entry 474; T2-NEXT: cmp r0, #0 475; T2-NEXT: mov.w r2, #2 476; T2-NEXT: mov.w r0, #4 477; T2-NEXT: it ne 478; T2-NEXT: movne r2, #5 479; T2-NEXT: cmp r1, #0 480; T2-NEXT: it ne 481; T2-NEXT: movne r0, #3 482; T2-NEXT: orrs r0, r2 483; T2-NEXT: bx lr 484entry: 485 %cmp = icmp ne i32 %x, 0 486 %cond = select i1 %cmp, i32 5, i32 2 487 %cmp1 = icmp ne i32 %y, 0 488 %cond2 = select i1 %cmp1, i32 3, i32 4 489 %or = or i32 %cond2, %cond 490 ret i32 %or 491} 492 493define i32 @t20(i32 %x, i32 %y) #0 { 494; ARM-LABEL: t20: 495; ARM: @ %bb.0: @ %entry 496; ARM-NEXT: cmn r0, #1 497; ARM-NEXT: mov r2, #2 498; ARM-NEXT: movwne r2, #5 499; ARM-NEXT: mov r0, #4 500; ARM-NEXT: cmn r1, #1 501; ARM-NEXT: movwne r0, #3 502; ARM-NEXT: orr r0, r0, r2 503; ARM-NEXT: bx lr 504; 505; T2-LABEL: t20: 506; T2: @ %bb.0: @ %entry 507; T2-NEXT: adds r0, #1 508; T2-NEXT: mov.w r0, #2 509; T2-NEXT: it ne 510; T2-NEXT: movne r0, #5 511; T2-NEXT: adds r1, #1 512; T2-NEXT: mov.w r1, #4 513; T2-NEXT: it ne 514; T2-NEXT: movne r1, #3 515; T2-NEXT: orrs r0, r1 516; T2-NEXT: bx lr 517entry: 518 %cmp = icmp ne i32 %x, -1 519 %cond = select i1 %cmp, i32 5, i32 2 520 %cmp1 = icmp ne i32 %y, -1 521 %cond2 = select i1 %cmp1, i32 3, i32 4 522 %or = or i32 %cond2, %cond 523 ret i32 %or 524} 525 526define <2 x i32> @t21(<2 x i32> %lhs, <2 x i32> %rhs) { 527; CHECK-LABEL: t21: 528; CHECK: @ %bb.0: 529; CHECK-NEXT: vmov d16, r2, r3 530; CHECK-NEXT: vmov d17, r0, r1 531; CHECK-NEXT: vceq.i32 d16, d17, d16 532; CHECK-NEXT: vmvn d16, d16 533; CHECK-NEXT: vshl.i32 d16, d16, #31 534; CHECK-NEXT: vshr.s32 d16, d16, #31 535; CHECK-NEXT: vmov r0, r1, d16 536; CHECK-NEXT: bx lr 537 %tst = icmp eq <2 x i32> %lhs, %rhs 538 %ntst = xor <2 x i1> %tst, <i1 1 , i1 undef> 539 %btst = sext <2 x i1> %ntst to <2 x i32> 540 ret <2 x i32> %btst 541} 542