1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=CHECK-T1 3; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2NODSP 4; RUN: llc < %s -mtriple=thumbv7em-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2DSP 5; RUN: llc < %s -mtriple=armv5t-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMNODPS 6; RUN: llc < %s -mtriple=armv5te-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMBASEDSP 7; RUN: llc < %s -mtriple=armv6-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMDSP 8 9declare i4 @llvm.ssub.sat.i4(i4, i4) 10declare i8 @llvm.ssub.sat.i8(i8, i8) 11declare i16 @llvm.ssub.sat.i16(i16, i16) 12declare i32 @llvm.ssub.sat.i32(i32, i32) 13declare i64 @llvm.ssub.sat.i64(i64, i64) 14declare <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32>, <4 x i32>) 15 16define i32 @func(i32 %x, i32 %y) nounwind { 17; CHECK-T1-LABEL: func: 18; CHECK-T1: @ %bb.0: 19; CHECK-T1-NEXT: .save {r4, lr} 20; CHECK-T1-NEXT: push {r4, lr} 21; CHECK-T1-NEXT: mov r2, r0 22; CHECK-T1-NEXT: movs r3, #1 23; CHECK-T1-NEXT: subs r0, r0, r1 24; CHECK-T1-NEXT: mov r4, r3 25; CHECK-T1-NEXT: bmi .LBB0_2 26; CHECK-T1-NEXT: @ %bb.1: 27; CHECK-T1-NEXT: movs r4, #0 28; CHECK-T1-NEXT: .LBB0_2: 29; CHECK-T1-NEXT: cmp r4, #0 30; CHECK-T1-NEXT: bne .LBB0_4 31; CHECK-T1-NEXT: @ %bb.3: 32; CHECK-T1-NEXT: lsls r3, r3, #31 33; CHECK-T1-NEXT: cmp r2, r1 34; CHECK-T1-NEXT: bvs .LBB0_5 35; CHECK-T1-NEXT: b .LBB0_6 36; CHECK-T1-NEXT: .LBB0_4: 37; CHECK-T1-NEXT: ldr r3, .LCPI0_0 38; CHECK-T1-NEXT: cmp r2, r1 39; CHECK-T1-NEXT: bvc .LBB0_6 40; CHECK-T1-NEXT: .LBB0_5: 41; CHECK-T1-NEXT: mov r0, r3 42; CHECK-T1-NEXT: .LBB0_6: 43; CHECK-T1-NEXT: pop {r4, pc} 44; CHECK-T1-NEXT: .p2align 2 45; CHECK-T1-NEXT: @ %bb.7: 46; CHECK-T1-NEXT: .LCPI0_0: 47; CHECK-T1-NEXT: .long 2147483647 @ 0x7fffffff 48; 49; CHECK-T2NODSP-LABEL: func: 50; CHECK-T2NODSP: @ %bb.0: 51; CHECK-T2NODSP-NEXT: subs.w r12, r0, r1 52; CHECK-T2NODSP-NEXT: mov.w r3, #0 53; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 54; CHECK-T2NODSP-NEXT: it mi 55; CHECK-T2NODSP-NEXT: movmi r3, #1 56; CHECK-T2NODSP-NEXT: cmp r3, #0 57; CHECK-T2NODSP-NEXT: it ne 58; CHECK-T2NODSP-NEXT: mvnne r2, #-2147483648 59; CHECK-T2NODSP-NEXT: cmp r0, r1 60; CHECK-T2NODSP-NEXT: it vc 61; CHECK-T2NODSP-NEXT: movvc r2, r12 62; CHECK-T2NODSP-NEXT: mov r0, r2 63; CHECK-T2NODSP-NEXT: bx lr 64; 65; CHECK-T2DSP-LABEL: func: 66; CHECK-T2DSP: @ %bb.0: 67; CHECK-T2DSP-NEXT: qsub r0, r0, r1 68; CHECK-T2DSP-NEXT: bx lr 69; 70; CHECK-ARMNODPS-LABEL: func: 71; CHECK-ARMNODPS: @ %bb.0: 72; CHECK-ARMNODPS-NEXT: subs r12, r0, r1 73; CHECK-ARMNODPS-NEXT: mov r3, #0 74; CHECK-ARMNODPS-NEXT: movmi r3, #1 75; CHECK-ARMNODPS-NEXT: mov r2, #-2147483648 76; CHECK-ARMNODPS-NEXT: cmp r3, #0 77; CHECK-ARMNODPS-NEXT: mvnne r2, #-2147483648 78; CHECK-ARMNODPS-NEXT: cmp r0, r1 79; CHECK-ARMNODPS-NEXT: movvc r2, r12 80; CHECK-ARMNODPS-NEXT: mov r0, r2 81; CHECK-ARMNODPS-NEXT: bx lr 82; 83; CHECK-ARMBASEDSP-LABEL: func: 84; CHECK-ARMBASEDSP: @ %bb.0: 85; CHECK-ARMBASEDSP-NEXT: qsub r0, r0, r1 86; CHECK-ARMBASEDSP-NEXT: bx lr 87; 88; CHECK-ARMDSP-LABEL: func: 89; CHECK-ARMDSP: @ %bb.0: 90; CHECK-ARMDSP-NEXT: qsub r0, r0, r1 91; CHECK-ARMDSP-NEXT: bx lr 92 %tmp = call i32 @llvm.ssub.sat.i32(i32 %x, i32 %y) 93 ret i32 %tmp 94} 95 96define i64 @func2(i64 %x, i64 %y) nounwind { 97; CHECK-T1-LABEL: func2: 98; CHECK-T1: @ %bb.0: 99; CHECK-T1-NEXT: .save {r4, r5, r6, r7, lr} 100; CHECK-T1-NEXT: push {r4, r5, r6, r7, lr} 101; CHECK-T1-NEXT: .pad #4 102; CHECK-T1-NEXT: sub sp, #4 103; CHECK-T1-NEXT: str r2, [sp] @ 4-byte Spill 104; CHECK-T1-NEXT: mov r2, r0 105; CHECK-T1-NEXT: movs r4, #1 106; CHECK-T1-NEXT: movs r0, #0 107; CHECK-T1-NEXT: cmp r3, #0 108; CHECK-T1-NEXT: mov r5, r4 109; CHECK-T1-NEXT: bge .LBB1_2 110; CHECK-T1-NEXT: @ %bb.1: 111; CHECK-T1-NEXT: mov r5, r0 112; CHECK-T1-NEXT: .LBB1_2: 113; CHECK-T1-NEXT: cmp r1, #0 114; CHECK-T1-NEXT: mov r7, r4 115; CHECK-T1-NEXT: bge .LBB1_4 116; CHECK-T1-NEXT: @ %bb.3: 117; CHECK-T1-NEXT: mov r7, r0 118; CHECK-T1-NEXT: .LBB1_4: 119; CHECK-T1-NEXT: subs r5, r7, r5 120; CHECK-T1-NEXT: subs r6, r5, #1 121; CHECK-T1-NEXT: sbcs r5, r6 122; CHECK-T1-NEXT: ldr r6, [sp] @ 4-byte Reload 123; CHECK-T1-NEXT: subs r6, r2, r6 124; CHECK-T1-NEXT: sbcs r1, r3 125; CHECK-T1-NEXT: cmp r1, #0 126; CHECK-T1-NEXT: mov r2, r4 127; CHECK-T1-NEXT: bge .LBB1_6 128; CHECK-T1-NEXT: @ %bb.5: 129; CHECK-T1-NEXT: mov r2, r0 130; CHECK-T1-NEXT: .LBB1_6: 131; CHECK-T1-NEXT: subs r0, r7, r2 132; CHECK-T1-NEXT: subs r2, r0, #1 133; CHECK-T1-NEXT: sbcs r0, r2 134; CHECK-T1-NEXT: ands r5, r0 135; CHECK-T1-NEXT: beq .LBB1_8 136; CHECK-T1-NEXT: @ %bb.7: 137; CHECK-T1-NEXT: asrs r6, r1, #31 138; CHECK-T1-NEXT: .LBB1_8: 139; CHECK-T1-NEXT: cmp r1, #0 140; CHECK-T1-NEXT: bmi .LBB1_10 141; CHECK-T1-NEXT: @ %bb.9: 142; CHECK-T1-NEXT: lsls r2, r4, #31 143; CHECK-T1-NEXT: cmp r5, #0 144; CHECK-T1-NEXT: beq .LBB1_11 145; CHECK-T1-NEXT: b .LBB1_12 146; CHECK-T1-NEXT: .LBB1_10: 147; CHECK-T1-NEXT: ldr r2, .LCPI1_0 148; CHECK-T1-NEXT: cmp r5, #0 149; CHECK-T1-NEXT: bne .LBB1_12 150; CHECK-T1-NEXT: .LBB1_11: 151; CHECK-T1-NEXT: mov r2, r1 152; CHECK-T1-NEXT: .LBB1_12: 153; CHECK-T1-NEXT: mov r0, r6 154; CHECK-T1-NEXT: mov r1, r2 155; CHECK-T1-NEXT: add sp, #4 156; CHECK-T1-NEXT: pop {r4, r5, r6, r7, pc} 157; CHECK-T1-NEXT: .p2align 2 158; CHECK-T1-NEXT: @ %bb.13: 159; CHECK-T1-NEXT: .LCPI1_0: 160; CHECK-T1-NEXT: .long 2147483647 @ 0x7fffffff 161; 162; CHECK-T2-LABEL: func2: 163; CHECK-T2: @ %bb.0: 164; CHECK-T2-NEXT: .save {r4, lr} 165; CHECK-T2-NEXT: push {r4, lr} 166; CHECK-T2-NEXT: cmp.w r3, #-1 167; CHECK-T2-NEXT: mov.w lr, #0 168; CHECK-T2-NEXT: it gt 169; CHECK-T2-NEXT: movgt.w lr, #1 170; CHECK-T2-NEXT: cmp.w r1, #-1 171; CHECK-T2-NEXT: mov.w r4, #0 172; CHECK-T2-NEXT: mov.w r12, #0 173; CHECK-T2-NEXT: it gt 174; CHECK-T2-NEXT: movgt r4, #1 175; CHECK-T2-NEXT: subs.w lr, r4, lr 176; CHECK-T2-NEXT: it ne 177; CHECK-T2-NEXT: movne.w lr, #1 178; CHECK-T2-NEXT: subs r0, r0, r2 179; CHECK-T2-NEXT: sbc.w r2, r1, r3 180; CHECK-T2-NEXT: cmp.w r2, #-1 181; CHECK-T2-NEXT: it gt 182; CHECK-T2-NEXT: movgt.w r12, #1 183; CHECK-T2-NEXT: subs.w r1, r4, r12 184; CHECK-T2-NEXT: it ne 185; CHECK-T2-NEXT: movne r1, #1 186; CHECK-T2-NEXT: ands.w r3, lr, r1 187; CHECK-T2-NEXT: mov.w r1, #-2147483648 188; CHECK-T2-NEXT: it ne 189; CHECK-T2-NEXT: asrne r0, r2, #31 190; CHECK-T2-NEXT: cmp r2, #0 191; CHECK-T2-NEXT: it mi 192; CHECK-T2-NEXT: mvnmi r1, #-2147483648 193; CHECK-T2-NEXT: cmp r3, #0 194; CHECK-T2-NEXT: it eq 195; CHECK-T2-NEXT: moveq r1, r2 196; CHECK-T2-NEXT: pop {r4, pc} 197; 198; CHECK-ARM-LABEL: func2: 199; CHECK-ARM: @ %bb.0: 200; CHECK-ARM-NEXT: .save {r4, lr} 201; CHECK-ARM-NEXT: push {r4, lr} 202; CHECK-ARM-NEXT: cmn r3, #1 203; CHECK-ARM-NEXT: mov lr, #0 204; CHECK-ARM-NEXT: movgt lr, #1 205; CHECK-ARM-NEXT: cmn r1, #1 206; CHECK-ARM-NEXT: mov r4, #0 207; CHECK-ARM-NEXT: mov r12, #0 208; CHECK-ARM-NEXT: movgt r4, #1 209; CHECK-ARM-NEXT: subs lr, r4, lr 210; CHECK-ARM-NEXT: movne lr, #1 211; CHECK-ARM-NEXT: subs r0, r0, r2 212; CHECK-ARM-NEXT: sbc r2, r1, r3 213; CHECK-ARM-NEXT: cmn r2, #1 214; CHECK-ARM-NEXT: movgt r12, #1 215; CHECK-ARM-NEXT: subs r1, r4, r12 216; CHECK-ARM-NEXT: movne r1, #1 217; CHECK-ARM-NEXT: ands r3, lr, r1 218; CHECK-ARM-NEXT: asrne r0, r2, #31 219; CHECK-ARM-NEXT: mov r1, #-2147483648 220; CHECK-ARM-NEXT: cmp r2, #0 221; CHECK-ARM-NEXT: mvnmi r1, #-2147483648 222; CHECK-ARM-NEXT: cmp r3, #0 223; CHECK-ARM-NEXT: moveq r1, r2 224; CHECK-ARM-NEXT: pop {r4, pc} 225 %tmp = call i64 @llvm.ssub.sat.i64(i64 %x, i64 %y) 226 ret i64 %tmp 227} 228 229define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind { 230; CHECK-T1-LABEL: func16: 231; CHECK-T1: @ %bb.0: 232; CHECK-T1-NEXT: subs r0, r0, r1 233; CHECK-T1-NEXT: ldr r1, .LCPI2_0 234; CHECK-T1-NEXT: cmp r0, r1 235; CHECK-T1-NEXT: blt .LBB2_2 236; CHECK-T1-NEXT: @ %bb.1: 237; CHECK-T1-NEXT: mov r0, r1 238; CHECK-T1-NEXT: .LBB2_2: 239; CHECK-T1-NEXT: ldr r1, .LCPI2_1 240; CHECK-T1-NEXT: cmp r0, r1 241; CHECK-T1-NEXT: bgt .LBB2_4 242; CHECK-T1-NEXT: @ %bb.3: 243; CHECK-T1-NEXT: mov r0, r1 244; CHECK-T1-NEXT: .LBB2_4: 245; CHECK-T1-NEXT: bx lr 246; CHECK-T1-NEXT: .p2align 2 247; CHECK-T1-NEXT: @ %bb.5: 248; CHECK-T1-NEXT: .LCPI2_0: 249; CHECK-T1-NEXT: .long 32767 @ 0x7fff 250; CHECK-T1-NEXT: .LCPI2_1: 251; CHECK-T1-NEXT: .long 4294934528 @ 0xffff8000 252; 253; CHECK-T2NODSP-LABEL: func16: 254; CHECK-T2NODSP: @ %bb.0: 255; CHECK-T2NODSP-NEXT: subs r0, r0, r1 256; CHECK-T2NODSP-NEXT: movw r1, #32767 257; CHECK-T2NODSP-NEXT: cmp r0, r1 258; CHECK-T2NODSP-NEXT: it lt 259; CHECK-T2NODSP-NEXT: movlt r1, r0 260; CHECK-T2NODSP-NEXT: movw r0, #32768 261; CHECK-T2NODSP-NEXT: cmn.w r1, #32768 262; CHECK-T2NODSP-NEXT: movt r0, #65535 263; CHECK-T2NODSP-NEXT: it gt 264; CHECK-T2NODSP-NEXT: movgt r0, r1 265; CHECK-T2NODSP-NEXT: bx lr 266; 267; CHECK-T2DSP-LABEL: func16: 268; CHECK-T2DSP: @ %bb.0: 269; CHECK-T2DSP-NEXT: qsub16 r0, r0, r1 270; CHECK-T2DSP-NEXT: sxth r0, r0 271; CHECK-T2DSP-NEXT: bx lr 272; 273; CHECK-ARMNODPS-LABEL: func16: 274; CHECK-ARMNODPS: @ %bb.0: 275; CHECK-ARMNODPS-NEXT: sub r0, r0, r1 276; CHECK-ARMNODPS-NEXT: mov r1, #255 277; CHECK-ARMNODPS-NEXT: orr r1, r1, #32512 278; CHECK-ARMNODPS-NEXT: cmp r0, r1 279; CHECK-ARMNODPS-NEXT: movlt r1, r0 280; CHECK-ARMNODPS-NEXT: ldr r0, .LCPI2_0 281; CHECK-ARMNODPS-NEXT: cmn r1, #32768 282; CHECK-ARMNODPS-NEXT: movgt r0, r1 283; CHECK-ARMNODPS-NEXT: bx lr 284; CHECK-ARMNODPS-NEXT: .p2align 2 285; CHECK-ARMNODPS-NEXT: @ %bb.1: 286; CHECK-ARMNODPS-NEXT: .LCPI2_0: 287; CHECK-ARMNODPS-NEXT: .long 4294934528 @ 0xffff8000 288; 289; CHECK-ARMBASEDSP-LABEL: func16: 290; CHECK-ARMBASEDSP: @ %bb.0: 291; CHECK-ARMBASEDSP-NEXT: lsl r0, r0, #16 292; CHECK-ARMBASEDSP-NEXT: lsl r1, r1, #16 293; CHECK-ARMBASEDSP-NEXT: qsub r0, r0, r1 294; CHECK-ARMBASEDSP-NEXT: asr r0, r0, #16 295; CHECK-ARMBASEDSP-NEXT: bx lr 296; 297; CHECK-ARMDSP-LABEL: func16: 298; CHECK-ARMDSP: @ %bb.0: 299; CHECK-ARMDSP-NEXT: qsub16 r0, r0, r1 300; CHECK-ARMDSP-NEXT: sxth r0, r0 301; CHECK-ARMDSP-NEXT: bx lr 302 %tmp = call i16 @llvm.ssub.sat.i16(i16 %x, i16 %y) 303 ret i16 %tmp 304} 305 306define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind { 307; CHECK-T1-LABEL: func8: 308; CHECK-T1: @ %bb.0: 309; CHECK-T1-NEXT: subs r0, r0, r1 310; CHECK-T1-NEXT: movs r1, #127 311; CHECK-T1-NEXT: cmp r0, #127 312; CHECK-T1-NEXT: blt .LBB3_2 313; CHECK-T1-NEXT: @ %bb.1: 314; CHECK-T1-NEXT: mov r0, r1 315; CHECK-T1-NEXT: .LBB3_2: 316; CHECK-T1-NEXT: mvns r1, r1 317; CHECK-T1-NEXT: cmp r0, r1 318; CHECK-T1-NEXT: bgt .LBB3_4 319; CHECK-T1-NEXT: @ %bb.3: 320; CHECK-T1-NEXT: mov r0, r1 321; CHECK-T1-NEXT: .LBB3_4: 322; CHECK-T1-NEXT: bx lr 323; 324; CHECK-T2NODSP-LABEL: func8: 325; CHECK-T2NODSP: @ %bb.0: 326; CHECK-T2NODSP-NEXT: subs r0, r0, r1 327; CHECK-T2NODSP-NEXT: cmp r0, #127 328; CHECK-T2NODSP-NEXT: it ge 329; CHECK-T2NODSP-NEXT: movge r0, #127 330; CHECK-T2NODSP-NEXT: cmn.w r0, #128 331; CHECK-T2NODSP-NEXT: it le 332; CHECK-T2NODSP-NEXT: mvnle r0, #127 333; CHECK-T2NODSP-NEXT: bx lr 334; 335; CHECK-T2DSP-LABEL: func8: 336; CHECK-T2DSP: @ %bb.0: 337; CHECK-T2DSP-NEXT: qsub8 r0, r0, r1 338; CHECK-T2DSP-NEXT: sxtb r0, r0 339; CHECK-T2DSP-NEXT: bx lr 340; 341; CHECK-ARMNODPS-LABEL: func8: 342; CHECK-ARMNODPS: @ %bb.0: 343; CHECK-ARMNODPS-NEXT: sub r0, r0, r1 344; CHECK-ARMNODPS-NEXT: cmp r0, #127 345; CHECK-ARMNODPS-NEXT: movge r0, #127 346; CHECK-ARMNODPS-NEXT: cmn r0, #128 347; CHECK-ARMNODPS-NEXT: mvnle r0, #127 348; CHECK-ARMNODPS-NEXT: bx lr 349; 350; CHECK-ARMBASEDSP-LABEL: func8: 351; CHECK-ARMBASEDSP: @ %bb.0: 352; CHECK-ARMBASEDSP-NEXT: lsl r0, r0, #24 353; CHECK-ARMBASEDSP-NEXT: lsl r1, r1, #24 354; CHECK-ARMBASEDSP-NEXT: qsub r0, r0, r1 355; CHECK-ARMBASEDSP-NEXT: asr r0, r0, #24 356; CHECK-ARMBASEDSP-NEXT: bx lr 357; 358; CHECK-ARMDSP-LABEL: func8: 359; CHECK-ARMDSP: @ %bb.0: 360; CHECK-ARMDSP-NEXT: qsub8 r0, r0, r1 361; CHECK-ARMDSP-NEXT: sxtb r0, r0 362; CHECK-ARMDSP-NEXT: bx lr 363 %tmp = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y) 364 ret i8 %tmp 365} 366 367define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind { 368; CHECK-T1-LABEL: func3: 369; CHECK-T1: @ %bb.0: 370; CHECK-T1-NEXT: subs r0, r0, r1 371; CHECK-T1-NEXT: movs r1, #7 372; CHECK-T1-NEXT: cmp r0, #7 373; CHECK-T1-NEXT: blt .LBB4_2 374; CHECK-T1-NEXT: @ %bb.1: 375; CHECK-T1-NEXT: mov r0, r1 376; CHECK-T1-NEXT: .LBB4_2: 377; CHECK-T1-NEXT: mvns r1, r1 378; CHECK-T1-NEXT: cmp r0, r1 379; CHECK-T1-NEXT: bgt .LBB4_4 380; CHECK-T1-NEXT: @ %bb.3: 381; CHECK-T1-NEXT: mov r0, r1 382; CHECK-T1-NEXT: .LBB4_4: 383; CHECK-T1-NEXT: bx lr 384; 385; CHECK-T2NODSP-LABEL: func3: 386; CHECK-T2NODSP: @ %bb.0: 387; CHECK-T2NODSP-NEXT: subs r0, r0, r1 388; CHECK-T2NODSP-NEXT: cmp r0, #7 389; CHECK-T2NODSP-NEXT: it ge 390; CHECK-T2NODSP-NEXT: movge r0, #7 391; CHECK-T2NODSP-NEXT: cmn.w r0, #8 392; CHECK-T2NODSP-NEXT: it le 393; CHECK-T2NODSP-NEXT: mvnle r0, #7 394; CHECK-T2NODSP-NEXT: bx lr 395; 396; CHECK-T2DSP-LABEL: func3: 397; CHECK-T2DSP: @ %bb.0: 398; CHECK-T2DSP-NEXT: lsls r1, r1, #28 399; CHECK-T2DSP-NEXT: lsls r0, r0, #28 400; CHECK-T2DSP-NEXT: qsub r0, r0, r1 401; CHECK-T2DSP-NEXT: asrs r0, r0, #28 402; CHECK-T2DSP-NEXT: bx lr 403; 404; CHECK-ARMNODPS-LABEL: func3: 405; CHECK-ARMNODPS: @ %bb.0: 406; CHECK-ARMNODPS-NEXT: sub r0, r0, r1 407; CHECK-ARMNODPS-NEXT: cmp r0, #7 408; CHECK-ARMNODPS-NEXT: movge r0, #7 409; CHECK-ARMNODPS-NEXT: cmn r0, #8 410; CHECK-ARMNODPS-NEXT: mvnle r0, #7 411; CHECK-ARMNODPS-NEXT: bx lr 412; 413; CHECK-ARMBASEDSP-LABEL: func3: 414; CHECK-ARMBASEDSP: @ %bb.0: 415; CHECK-ARMBASEDSP-NEXT: lsl r0, r0, #28 416; CHECK-ARMBASEDSP-NEXT: lsl r1, r1, #28 417; CHECK-ARMBASEDSP-NEXT: qsub r0, r0, r1 418; CHECK-ARMBASEDSP-NEXT: asr r0, r0, #28 419; CHECK-ARMBASEDSP-NEXT: bx lr 420; 421; CHECK-ARMDSP-LABEL: func3: 422; CHECK-ARMDSP: @ %bb.0: 423; CHECK-ARMDSP-NEXT: lsl r0, r0, #28 424; CHECK-ARMDSP-NEXT: lsl r1, r1, #28 425; CHECK-ARMDSP-NEXT: qsub r0, r0, r1 426; CHECK-ARMDSP-NEXT: asr r0, r0, #28 427; CHECK-ARMDSP-NEXT: bx lr 428 %tmp = call i4 @llvm.ssub.sat.i4(i4 %x, i4 %y) 429 ret i4 %tmp 430} 431 432define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind { 433; CHECK-T1-LABEL: vec: 434; CHECK-T1: @ %bb.0: 435; CHECK-T1-NEXT: .save {r4, r5, r6, r7, lr} 436; CHECK-T1-NEXT: push {r4, r5, r6, r7, lr} 437; CHECK-T1-NEXT: .pad #12 438; CHECK-T1-NEXT: sub sp, #12 439; CHECK-T1-NEXT: str r3, [sp] @ 4-byte Spill 440; CHECK-T1-NEXT: mov r4, r1 441; CHECK-T1-NEXT: mov r1, r0 442; CHECK-T1-NEXT: ldr r5, [sp, #32] 443; CHECK-T1-NEXT: movs r7, #1 444; CHECK-T1-NEXT: movs r0, #0 445; CHECK-T1-NEXT: str r0, [sp, #8] @ 4-byte Spill 446; CHECK-T1-NEXT: subs r0, r1, r5 447; CHECK-T1-NEXT: str r0, [sp, #4] @ 4-byte Spill 448; CHECK-T1-NEXT: mov r6, r7 449; CHECK-T1-NEXT: bmi .LBB5_2 450; CHECK-T1-NEXT: @ %bb.1: 451; CHECK-T1-NEXT: ldr r6, [sp, #8] @ 4-byte Reload 452; CHECK-T1-NEXT: .LBB5_2: 453; CHECK-T1-NEXT: lsls r3, r7, #31 454; CHECK-T1-NEXT: ldr r0, .LCPI5_0 455; CHECK-T1-NEXT: cmp r6, #0 456; CHECK-T1-NEXT: mov r6, r0 457; CHECK-T1-NEXT: bne .LBB5_4 458; CHECK-T1-NEXT: @ %bb.3: 459; CHECK-T1-NEXT: mov r6, r3 460; CHECK-T1-NEXT: .LBB5_4: 461; CHECK-T1-NEXT: cmp r1, r5 462; CHECK-T1-NEXT: bvc .LBB5_6 463; CHECK-T1-NEXT: @ %bb.5: 464; CHECK-T1-NEXT: str r6, [sp, #4] @ 4-byte Spill 465; CHECK-T1-NEXT: .LBB5_6: 466; CHECK-T1-NEXT: ldr r5, [sp, #36] 467; CHECK-T1-NEXT: subs r1, r4, r5 468; CHECK-T1-NEXT: mov r6, r7 469; CHECK-T1-NEXT: bmi .LBB5_8 470; CHECK-T1-NEXT: @ %bb.7: 471; CHECK-T1-NEXT: ldr r6, [sp, #8] @ 4-byte Reload 472; CHECK-T1-NEXT: .LBB5_8: 473; CHECK-T1-NEXT: cmp r6, #0 474; CHECK-T1-NEXT: mov r6, r0 475; CHECK-T1-NEXT: bne .LBB5_10 476; CHECK-T1-NEXT: @ %bb.9: 477; CHECK-T1-NEXT: mov r6, r3 478; CHECK-T1-NEXT: .LBB5_10: 479; CHECK-T1-NEXT: cmp r4, r5 480; CHECK-T1-NEXT: bvc .LBB5_12 481; CHECK-T1-NEXT: @ %bb.11: 482; CHECK-T1-NEXT: mov r1, r6 483; CHECK-T1-NEXT: .LBB5_12: 484; CHECK-T1-NEXT: ldr r5, [sp, #40] 485; CHECK-T1-NEXT: subs r4, r2, r5 486; CHECK-T1-NEXT: mov r6, r7 487; CHECK-T1-NEXT: bmi .LBB5_14 488; CHECK-T1-NEXT: @ %bb.13: 489; CHECK-T1-NEXT: ldr r6, [sp, #8] @ 4-byte Reload 490; CHECK-T1-NEXT: .LBB5_14: 491; CHECK-T1-NEXT: cmp r6, #0 492; CHECK-T1-NEXT: mov r6, r0 493; CHECK-T1-NEXT: bne .LBB5_16 494; CHECK-T1-NEXT: @ %bb.15: 495; CHECK-T1-NEXT: mov r6, r3 496; CHECK-T1-NEXT: .LBB5_16: 497; CHECK-T1-NEXT: cmp r2, r5 498; CHECK-T1-NEXT: bvc .LBB5_18 499; CHECK-T1-NEXT: @ %bb.17: 500; CHECK-T1-NEXT: mov r4, r6 501; CHECK-T1-NEXT: .LBB5_18: 502; CHECK-T1-NEXT: ldr r2, [sp, #44] 503; CHECK-T1-NEXT: ldr r6, [sp] @ 4-byte Reload 504; CHECK-T1-NEXT: subs r5, r6, r2 505; CHECK-T1-NEXT: bpl .LBB5_23 506; CHECK-T1-NEXT: @ %bb.19: 507; CHECK-T1-NEXT: cmp r7, #0 508; CHECK-T1-NEXT: beq .LBB5_24 509; CHECK-T1-NEXT: .LBB5_20: 510; CHECK-T1-NEXT: cmp r6, r2 511; CHECK-T1-NEXT: bvc .LBB5_22 512; CHECK-T1-NEXT: .LBB5_21: 513; CHECK-T1-NEXT: mov r5, r0 514; CHECK-T1-NEXT: .LBB5_22: 515; CHECK-T1-NEXT: ldr r0, [sp, #4] @ 4-byte Reload 516; CHECK-T1-NEXT: mov r2, r4 517; CHECK-T1-NEXT: mov r3, r5 518; CHECK-T1-NEXT: add sp, #12 519; CHECK-T1-NEXT: pop {r4, r5, r6, r7, pc} 520; CHECK-T1-NEXT: .LBB5_23: 521; CHECK-T1-NEXT: ldr r7, [sp, #8] @ 4-byte Reload 522; CHECK-T1-NEXT: cmp r7, #0 523; CHECK-T1-NEXT: bne .LBB5_20 524; CHECK-T1-NEXT: .LBB5_24: 525; CHECK-T1-NEXT: mov r0, r3 526; CHECK-T1-NEXT: cmp r6, r2 527; CHECK-T1-NEXT: bvs .LBB5_21 528; CHECK-T1-NEXT: b .LBB5_22 529; CHECK-T1-NEXT: .p2align 2 530; CHECK-T1-NEXT: @ %bb.25: 531; CHECK-T1-NEXT: .LCPI5_0: 532; CHECK-T1-NEXT: .long 2147483647 @ 0x7fffffff 533; 534; CHECK-T2NODSP-LABEL: vec: 535; CHECK-T2NODSP: @ %bb.0: 536; CHECK-T2NODSP-NEXT: .save {r4, r5, r6, r7, lr} 537; CHECK-T2NODSP-NEXT: push {r4, r5, r6, r7, lr} 538; CHECK-T2NODSP-NEXT: .pad #4 539; CHECK-T2NODSP-NEXT: sub sp, #4 540; CHECK-T2NODSP-NEXT: ldr r4, [sp, #24] 541; CHECK-T2NODSP-NEXT: mov lr, r0 542; CHECK-T2NODSP-NEXT: ldr r7, [sp, #28] 543; CHECK-T2NODSP-NEXT: movs r5, #0 544; CHECK-T2NODSP-NEXT: subs r6, r0, r4 545; CHECK-T2NODSP-NEXT: mov.w r0, #0 546; CHECK-T2NODSP-NEXT: it mi 547; CHECK-T2NODSP-NEXT: movmi r0, #1 548; CHECK-T2NODSP-NEXT: cmp r0, #0 549; CHECK-T2NODSP-NEXT: mov.w r0, #-2147483648 550; CHECK-T2NODSP-NEXT: mov.w r12, #-2147483648 551; CHECK-T2NODSP-NEXT: it ne 552; CHECK-T2NODSP-NEXT: mvnne r0, #-2147483648 553; CHECK-T2NODSP-NEXT: cmp lr, r4 554; CHECK-T2NODSP-NEXT: it vc 555; CHECK-T2NODSP-NEXT: movvc r0, r6 556; CHECK-T2NODSP-NEXT: subs r6, r1, r7 557; CHECK-T2NODSP-NEXT: mov.w r4, #0 558; CHECK-T2NODSP-NEXT: mov.w lr, #-2147483648 559; CHECK-T2NODSP-NEXT: it mi 560; CHECK-T2NODSP-NEXT: movmi r4, #1 561; CHECK-T2NODSP-NEXT: cmp r4, #0 562; CHECK-T2NODSP-NEXT: it ne 563; CHECK-T2NODSP-NEXT: mvnne lr, #-2147483648 564; CHECK-T2NODSP-NEXT: cmp r1, r7 565; CHECK-T2NODSP-NEXT: ldr r1, [sp, #32] 566; CHECK-T2NODSP-NEXT: mov.w r4, #0 567; CHECK-T2NODSP-NEXT: it vc 568; CHECK-T2NODSP-NEXT: movvc lr, r6 569; CHECK-T2NODSP-NEXT: subs r6, r2, r1 570; CHECK-T2NODSP-NEXT: it mi 571; CHECK-T2NODSP-NEXT: movmi r4, #1 572; CHECK-T2NODSP-NEXT: cmp r4, #0 573; CHECK-T2NODSP-NEXT: mov.w r4, #-2147483648 574; CHECK-T2NODSP-NEXT: it ne 575; CHECK-T2NODSP-NEXT: mvnne r4, #-2147483648 576; CHECK-T2NODSP-NEXT: cmp r2, r1 577; CHECK-T2NODSP-NEXT: ldr r1, [sp, #36] 578; CHECK-T2NODSP-NEXT: it vc 579; CHECK-T2NODSP-NEXT: movvc r4, r6 580; CHECK-T2NODSP-NEXT: subs r2, r3, r1 581; CHECK-T2NODSP-NEXT: it mi 582; CHECK-T2NODSP-NEXT: movmi r5, #1 583; CHECK-T2NODSP-NEXT: cmp r5, #0 584; CHECK-T2NODSP-NEXT: it ne 585; CHECK-T2NODSP-NEXT: mvnne r12, #-2147483648 586; CHECK-T2NODSP-NEXT: cmp r3, r1 587; CHECK-T2NODSP-NEXT: it vc 588; CHECK-T2NODSP-NEXT: movvc r12, r2 589; CHECK-T2NODSP-NEXT: mov r1, lr 590; CHECK-T2NODSP-NEXT: mov r2, r4 591; CHECK-T2NODSP-NEXT: mov r3, r12 592; CHECK-T2NODSP-NEXT: add sp, #4 593; CHECK-T2NODSP-NEXT: pop {r4, r5, r6, r7, pc} 594; 595; CHECK-T2DSP-LABEL: vec: 596; CHECK-T2DSP: @ %bb.0: 597; CHECK-T2DSP-NEXT: ldr.w r12, [sp] 598; CHECK-T2DSP-NEXT: qsub r0, r0, r12 599; CHECK-T2DSP-NEXT: ldr.w r12, [sp, #4] 600; CHECK-T2DSP-NEXT: qsub r1, r1, r12 601; CHECK-T2DSP-NEXT: ldr.w r12, [sp, #8] 602; CHECK-T2DSP-NEXT: qsub r2, r2, r12 603; CHECK-T2DSP-NEXT: ldr.w r12, [sp, #12] 604; CHECK-T2DSP-NEXT: qsub r3, r3, r12 605; CHECK-T2DSP-NEXT: bx lr 606; 607; CHECK-ARMNODPS-LABEL: vec: 608; CHECK-ARMNODPS: @ %bb.0: 609; CHECK-ARMNODPS-NEXT: .save {r4, r5, r6, r7, r11, lr} 610; CHECK-ARMNODPS-NEXT: push {r4, r5, r6, r7, r11, lr} 611; CHECK-ARMNODPS-NEXT: ldr r4, [sp, #24] 612; CHECK-ARMNODPS-NEXT: mov lr, r0 613; CHECK-ARMNODPS-NEXT: ldr r7, [sp, #28] 614; CHECK-ARMNODPS-NEXT: mov r5, #0 615; CHECK-ARMNODPS-NEXT: subs r6, r0, r4 616; CHECK-ARMNODPS-NEXT: mov r0, #0 617; CHECK-ARMNODPS-NEXT: movmi r0, #1 618; CHECK-ARMNODPS-NEXT: cmp r0, #0 619; CHECK-ARMNODPS-NEXT: mov r0, #-2147483648 620; CHECK-ARMNODPS-NEXT: mov r12, #-2147483648 621; CHECK-ARMNODPS-NEXT: mvnne r0, #-2147483648 622; CHECK-ARMNODPS-NEXT: cmp lr, r4 623; CHECK-ARMNODPS-NEXT: movvc r0, r6 624; CHECK-ARMNODPS-NEXT: subs r6, r1, r7 625; CHECK-ARMNODPS-NEXT: mov r4, #0 626; CHECK-ARMNODPS-NEXT: mov lr, #-2147483648 627; CHECK-ARMNODPS-NEXT: movmi r4, #1 628; CHECK-ARMNODPS-NEXT: cmp r4, #0 629; CHECK-ARMNODPS-NEXT: mvnne lr, #-2147483648 630; CHECK-ARMNODPS-NEXT: cmp r1, r7 631; CHECK-ARMNODPS-NEXT: ldr r1, [sp, #32] 632; CHECK-ARMNODPS-NEXT: movvc lr, r6 633; CHECK-ARMNODPS-NEXT: mov r4, #0 634; CHECK-ARMNODPS-NEXT: subs r6, r2, r1 635; CHECK-ARMNODPS-NEXT: movmi r4, #1 636; CHECK-ARMNODPS-NEXT: cmp r4, #0 637; CHECK-ARMNODPS-NEXT: mov r4, #-2147483648 638; CHECK-ARMNODPS-NEXT: mvnne r4, #-2147483648 639; CHECK-ARMNODPS-NEXT: cmp r2, r1 640; CHECK-ARMNODPS-NEXT: ldr r1, [sp, #36] 641; CHECK-ARMNODPS-NEXT: movvc r4, r6 642; CHECK-ARMNODPS-NEXT: subs r2, r3, r1 643; CHECK-ARMNODPS-NEXT: movmi r5, #1 644; CHECK-ARMNODPS-NEXT: cmp r5, #0 645; CHECK-ARMNODPS-NEXT: mvnne r12, #-2147483648 646; CHECK-ARMNODPS-NEXT: cmp r3, r1 647; CHECK-ARMNODPS-NEXT: movvc r12, r2 648; CHECK-ARMNODPS-NEXT: mov r1, lr 649; CHECK-ARMNODPS-NEXT: mov r2, r4 650; CHECK-ARMNODPS-NEXT: mov r3, r12 651; CHECK-ARMNODPS-NEXT: pop {r4, r5, r6, r7, r11, pc} 652; 653; CHECK-ARMBASEDSP-LABEL: vec: 654; CHECK-ARMBASEDSP: @ %bb.0: 655; CHECK-ARMBASEDSP-NEXT: ldr r12, [sp] 656; CHECK-ARMBASEDSP-NEXT: qsub r0, r0, r12 657; CHECK-ARMBASEDSP-NEXT: ldr r12, [sp, #4] 658; CHECK-ARMBASEDSP-NEXT: qsub r1, r1, r12 659; CHECK-ARMBASEDSP-NEXT: ldr r12, [sp, #8] 660; CHECK-ARMBASEDSP-NEXT: qsub r2, r2, r12 661; CHECK-ARMBASEDSP-NEXT: ldr r12, [sp, #12] 662; CHECK-ARMBASEDSP-NEXT: qsub r3, r3, r12 663; CHECK-ARMBASEDSP-NEXT: bx lr 664; 665; CHECK-ARMDSP-LABEL: vec: 666; CHECK-ARMDSP: @ %bb.0: 667; CHECK-ARMDSP-NEXT: ldr r12, [sp] 668; CHECK-ARMDSP-NEXT: qsub r0, r0, r12 669; CHECK-ARMDSP-NEXT: ldr r12, [sp, #4] 670; CHECK-ARMDSP-NEXT: qsub r1, r1, r12 671; CHECK-ARMDSP-NEXT: ldr r12, [sp, #8] 672; CHECK-ARMDSP-NEXT: qsub r2, r2, r12 673; CHECK-ARMDSP-NEXT: ldr r12, [sp, #12] 674; CHECK-ARMDSP-NEXT: qsub r3, r3, r12 675; CHECK-ARMDSP-NEXT: bx lr 676 %tmp = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %x, <4 x i32> %y) 677 ret <4 x i32> %tmp 678} 679