450 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=thumbv6m-none-unknown-eabi -mcpu=cortex-m0 | FileCheck %s --check-prefix=ARM3 4declare i4 @llvm.umul.fix.sat.i4 (i4, i4, i32)5declare i32 @llvm.umul.fix.sat.i32 (i32, i32, i32)6declare i64 @llvm.umul.fix.sat.i64 (i64, i64, i32)7 8define i32 @func(i32 %x, i32 %y) nounwind {9; ARM-LABEL: func:10; ARM: @ %bb.0:11; ARM-NEXT: .save {r4, lr}12; ARM-NEXT: push {r4, lr}13; ARM-NEXT: mov r2, r114; ARM-NEXT: movs r4, #015; ARM-NEXT: mov r1, r416; ARM-NEXT: mov r3, r417; ARM-NEXT: bl __aeabi_lmul18; ARM-NEXT: cmp r1, #319; ARM-NEXT: bhi .LBB0_220; ARM-NEXT: @ %bb.1:21; ARM-NEXT: lsrs r0, r0, #222; ARM-NEXT: lsls r1, r1, #3023; ARM-NEXT: adds r0, r1, r024; ARM-NEXT: pop {r4, pc}25; ARM-NEXT: .LBB0_2:26; ARM-NEXT: mvns r0, r427; ARM-NEXT: pop {r4, pc}28 %tmp = call i32 @llvm.umul.fix.sat.i32(i32 %x, i32 %y, i32 2)29 ret i32 %tmp30}31 32define i64 @func2(i64 %x, i64 %y) nounwind {33; ARM-LABEL: func2:34; ARM: @ %bb.0:35; ARM-NEXT: .save {r4, r5, r6, r7, lr}36; ARM-NEXT: push {r4, r5, r6, r7, lr}37; ARM-NEXT: .pad #2038; ARM-NEXT: sub sp, #2039; ARM-NEXT: str r3, [sp, #12] @ 4-byte Spill40; ARM-NEXT: mov r6, r241; ARM-NEXT: mov r7, r142; ARM-NEXT: str r1, [sp, #8] @ 4-byte Spill43; ARM-NEXT: mov r5, r044; ARM-NEXT: movs r4, #045; ARM-NEXT: mov r1, r446; ARM-NEXT: mov r3, r447; ARM-NEXT: bl __aeabi_lmul48; ARM-NEXT: str r0, [sp, #16] @ 4-byte Spill49; ARM-NEXT: str r1, [sp, #4] @ 4-byte Spill50; ARM-NEXT: mov r0, r751; ARM-NEXT: mov r1, r452; ARM-NEXT: mov r2, r653; ARM-NEXT: mov r3, r454; ARM-NEXT: bl __aeabi_lmul55; ARM-NEXT: mov r6, r156; ARM-NEXT: ldr r1, [sp, #4] @ 4-byte Reload57; ARM-NEXT: adds r7, r0, r158; ARM-NEXT: adcs r6, r459; ARM-NEXT: mov r0, r560; ARM-NEXT: mov r1, r461; ARM-NEXT: ldr r5, [sp, #12] @ 4-byte Reload62; ARM-NEXT: mov r2, r563; ARM-NEXT: mov r3, r464; ARM-NEXT: bl __aeabi_lmul65; ARM-NEXT: adds r0, r0, r766; ARM-NEXT: str r0, [sp, #4] @ 4-byte Spill67; ARM-NEXT: adcs r1, r468; ARM-NEXT: adds r6, r6, r169; ARM-NEXT: mov r7, r470; ARM-NEXT: adcs r7, r471; ARM-NEXT: ldr r0, [sp, #8] @ 4-byte Reload72; ARM-NEXT: mov r1, r473; ARM-NEXT: mov r2, r574; ARM-NEXT: mov r3, r475; ARM-NEXT: bl __aeabi_lmul76; ARM-NEXT: adds r0, r0, r677; ARM-NEXT: adcs r1, r778; ARM-NEXT: lsrs r6, r0, #279; ARM-NEXT: orrs r6, r180; ARM-NEXT: lsls r0, r0, #3081; ARM-NEXT: ldr r3, [sp, #4] @ 4-byte Reload82; ARM-NEXT: lsrs r1, r3, #283; ARM-NEXT: adds r2, r0, r184; ARM-NEXT: lsls r0, r3, #3085; ARM-NEXT: ldr r1, [sp, #16] @ 4-byte Reload86; ARM-NEXT: lsrs r1, r1, #287; ARM-NEXT: adds r3, r0, r188; ARM-NEXT: mvns r1, r489; ARM-NEXT: cmp r6, #090; ARM-NEXT: mov r0, r191; ARM-NEXT: beq .LBB1_392; ARM-NEXT: @ %bb.1:93; ARM-NEXT: beq .LBB1_494; ARM-NEXT: .LBB1_2:95; ARM-NEXT: add sp, #2096; ARM-NEXT: pop {r4, r5, r6, r7, pc}97; ARM-NEXT: .LBB1_3:98; ARM-NEXT: mov r0, r399; ARM-NEXT: bne .LBB1_2100; ARM-NEXT: .LBB1_4:101; ARM-NEXT: mov r1, r2102; ARM-NEXT: add sp, #20103; ARM-NEXT: pop {r4, r5, r6, r7, pc}104 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 2)105 ret i64 %tmp106}107 108define i4 @func3(i4 %x, i4 %y) nounwind {109; ARM-LABEL: func3:110; ARM: @ %bb.0:111; ARM-NEXT: .save {r4, lr}112; ARM-NEXT: push {r4, lr}113; ARM-NEXT: movs r2, #15114; ARM-NEXT: ands r2, r1115; ARM-NEXT: lsls r0, r0, #28116; ARM-NEXT: movs r4, #0117; ARM-NEXT: mov r1, r4118; ARM-NEXT: mov r3, r4119; ARM-NEXT: bl __aeabi_lmul120; ARM-NEXT: cmp r1, #3121; ARM-NEXT: bhi .LBB2_2122; ARM-NEXT: @ %bb.1:123; ARM-NEXT: lsrs r0, r0, #2124; ARM-NEXT: lsls r1, r1, #30125; ARM-NEXT: adds r0, r1, r0126; ARM-NEXT: lsrs r0, r0, #28127; ARM-NEXT: pop {r4, pc}128; ARM-NEXT: .LBB2_2:129; ARM-NEXT: mvns r0, r4130; ARM-NEXT: lsrs r0, r0, #28131; ARM-NEXT: pop {r4, pc}132 %tmp = call i4 @llvm.umul.fix.sat.i4(i4 %x, i4 %y, i32 2)133 ret i4 %tmp134}135 136;; These result in regular integer multiplication with a saturation check.137define i32 @func4(i32 %x, i32 %y) nounwind {138; ARM-LABEL: func4:139; ARM: @ %bb.0:140; ARM-NEXT: .save {r4, lr}141; ARM-NEXT: push {r4, lr}142; ARM-NEXT: mov r2, r1143; ARM-NEXT: movs r4, #0144; ARM-NEXT: mov r1, r4145; ARM-NEXT: mov r3, r4146; ARM-NEXT: bl __aeabi_lmul147; ARM-NEXT: cmp r1, #0148; ARM-NEXT: bls .LBB3_2149; ARM-NEXT: @ %bb.1:150; ARM-NEXT: mvns r0, r4151; ARM-NEXT: .LBB3_2:152; ARM-NEXT: pop {r4, pc}153 %tmp = call i32 @llvm.umul.fix.sat.i32(i32 %x, i32 %y, i32 0)154 ret i32 %tmp155}156 157define i64 @func5(i64 %x, i64 %y) {158; ARM-LABEL: func5:159; ARM: @ %bb.0:160; ARM-NEXT: .save {r4, r5, r6, r7, lr}161; ARM-NEXT: push {r4, r5, r6, r7, lr}162; ARM-NEXT: .pad #12163; ARM-NEXT: sub sp, #12164; ARM-NEXT: mov r6, r3165; ARM-NEXT: str r2, [sp, #8] @ 4-byte Spill166; ARM-NEXT: mov r4, r1167; ARM-NEXT: mov r2, r0168; ARM-NEXT: str r0, [sp, #4] @ 4-byte Spill169; ARM-NEXT: movs r5, #0170; ARM-NEXT: mov r0, r3171; ARM-NEXT: mov r1, r5172; ARM-NEXT: mov r3, r5173; ARM-NEXT: bl __aeabi_lmul174; ARM-NEXT: str r0, [sp] @ 4-byte Spill175; ARM-NEXT: mov r7, r1176; ARM-NEXT: subs r0, r1, #1177; ARM-NEXT: sbcs r7, r0178; ARM-NEXT: mov r0, r4179; ARM-NEXT: mov r1, r5180; ARM-NEXT: ldr r2, [sp, #8] @ 4-byte Reload181; ARM-NEXT: mov r3, r5182; ARM-NEXT: bl __aeabi_lmul183; ARM-NEXT: subs r2, r1, #1184; ARM-NEXT: sbcs r1, r2185; ARM-NEXT: subs r2, r6, #1186; ARM-NEXT: sbcs r6, r2187; ARM-NEXT: subs r2, r4, #1188; ARM-NEXT: sbcs r4, r2189; ARM-NEXT: ands r4, r6190; ARM-NEXT: orrs r4, r1191; ARM-NEXT: orrs r4, r7192; ARM-NEXT: ldr r1, [sp] @ 4-byte Reload193; ARM-NEXT: adds r6, r0, r1194; ARM-NEXT: ldr r0, [sp, #4] @ 4-byte Reload195; ARM-NEXT: mov r1, r5196; ARM-NEXT: ldr r2, [sp, #8] @ 4-byte Reload197; ARM-NEXT: mov r3, r5198; ARM-NEXT: bl __aeabi_lmul199; ARM-NEXT: adds r3, r1, r6200; ARM-NEXT: mov r2, r5201; ARM-NEXT: adcs r2, r5202; ARM-NEXT: orrs r2, r4203; ARM-NEXT: mvns r1, r5204; ARM-NEXT: cmp r2, #0205; ARM-NEXT: mov r2, r1206; ARM-NEXT: bne .LBB4_2207; ARM-NEXT: @ %bb.1:208; ARM-NEXT: mov r2, r0209; ARM-NEXT: .LBB4_2:210; ARM-NEXT: bne .LBB4_4211; ARM-NEXT: @ %bb.3:212; ARM-NEXT: mov r1, r3213; ARM-NEXT: .LBB4_4:214; ARM-NEXT: mov r0, r2215; ARM-NEXT: add sp, #12216; ARM-NEXT: pop {r4, r5, r6, r7, pc}217 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 0)218 ret i64 %tmp219}220 221define i4 @func6(i4 %x, i4 %y) nounwind {222; ARM-LABEL: func6:223; ARM: @ %bb.0:224; ARM-NEXT: .save {r4, lr}225; ARM-NEXT: push {r4, lr}226; ARM-NEXT: movs r2, #15227; ARM-NEXT: ands r2, r1228; ARM-NEXT: lsls r0, r0, #28229; ARM-NEXT: movs r4, #0230; ARM-NEXT: mov r1, r4231; ARM-NEXT: mov r3, r4232; ARM-NEXT: bl __aeabi_lmul233; ARM-NEXT: cmp r1, #0234; ARM-NEXT: bls .LBB5_2235; ARM-NEXT: @ %bb.1:236; ARM-NEXT: mvns r0, r4237; ARM-NEXT: .LBB5_2:238; ARM-NEXT: lsrs r0, r0, #28239; ARM-NEXT: pop {r4, pc}240 %tmp = call i4 @llvm.umul.fix.sat.i4(i4 %x, i4 %y, i32 0)241 ret i4 %tmp242}243 244define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {245; ARM-LABEL: vec2:246; ARM: @ %bb.0:247; ARM-NEXT: .save {r4, r5, r6, r7, lr}248; ARM-NEXT: push {r4, r5, r6, r7, lr}249; ARM-NEXT: .pad #12250; ARM-NEXT: sub sp, #12251; ARM-NEXT: str r3, [sp, #8] @ 4-byte Spill252; ARM-NEXT: mov r7, r2253; ARM-NEXT: mov r5, r1254; ARM-NEXT: ldr r2, [sp, #32]255; ARM-NEXT: movs r6, #0256; ARM-NEXT: mov r1, r6257; ARM-NEXT: mov r3, r6258; ARM-NEXT: bl __aeabi_lmul259; ARM-NEXT: mvns r4, r6260; ARM-NEXT: cmp r1, #0261; ARM-NEXT: mov r1, r4262; ARM-NEXT: bhi .LBB6_2263; ARM-NEXT: @ %bb.1:264; ARM-NEXT: mov r1, r0265; ARM-NEXT: .LBB6_2:266; ARM-NEXT: str r1, [sp, #4] @ 4-byte Spill267; ARM-NEXT: ldr r2, [sp, #36]268; ARM-NEXT: mov r0, r5269; ARM-NEXT: mov r1, r6270; ARM-NEXT: mov r3, r6271; ARM-NEXT: bl __aeabi_lmul272; ARM-NEXT: cmp r1, #0273; ARM-NEXT: mov r5, r4274; ARM-NEXT: bhi .LBB6_4275; ARM-NEXT: @ %bb.3:276; ARM-NEXT: mov r5, r0277; ARM-NEXT: .LBB6_4:278; ARM-NEXT: ldr r2, [sp, #40]279; ARM-NEXT: mov r0, r7280; ARM-NEXT: mov r1, r6281; ARM-NEXT: mov r3, r6282; ARM-NEXT: bl __aeabi_lmul283; ARM-NEXT: cmp r1, #0284; ARM-NEXT: mov r7, r4285; ARM-NEXT: bhi .LBB6_6286; ARM-NEXT: @ %bb.5:287; ARM-NEXT: mov r7, r0288; ARM-NEXT: .LBB6_6:289; ARM-NEXT: ldr r2, [sp, #44]290; ARM-NEXT: ldr r0, [sp, #8] @ 4-byte Reload291; ARM-NEXT: mov r1, r6292; ARM-NEXT: mov r3, r6293; ARM-NEXT: bl __aeabi_lmul294; ARM-NEXT: cmp r1, #0295; ARM-NEXT: bhi .LBB6_8296; ARM-NEXT: @ %bb.7:297; ARM-NEXT: mov r4, r0298; ARM-NEXT: .LBB6_8:299; ARM-NEXT: ldr r0, [sp, #4] @ 4-byte Reload300; ARM-NEXT: mov r1, r5301; ARM-NEXT: mov r2, r7302; ARM-NEXT: mov r3, r4303; ARM-NEXT: add sp, #12304; ARM-NEXT: pop {r4, r5, r6, r7, pc}305 %tmp = call <4 x i32> @llvm.umul.fix.sat.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0)306 ret <4 x i32> %tmp307}308 309define i64 @func7(i64 %x, i64 %y) nounwind {310; ARM-LABEL: func7:311; ARM: @ %bb.0:312; ARM-NEXT: .save {r4, r5, r6, r7, lr}313; ARM-NEXT: push {r4, r5, r6, r7, lr}314; ARM-NEXT: .pad #12315; ARM-NEXT: sub sp, #12316; ARM-NEXT: str r3, [sp, #8] @ 4-byte Spill317; ARM-NEXT: mov r5, r2318; ARM-NEXT: mov r6, r1319; ARM-NEXT: str r1, [sp, #4] @ 4-byte Spill320; ARM-NEXT: mov r7, r0321; ARM-NEXT: movs r4, #0322; ARM-NEXT: mov r1, r4323; ARM-NEXT: mov r3, r4324; ARM-NEXT: bl __aeabi_lmul325; ARM-NEXT: str r1, [sp] @ 4-byte Spill326; ARM-NEXT: mov r0, r6327; ARM-NEXT: mov r1, r4328; ARM-NEXT: mov r2, r5329; ARM-NEXT: mov r3, r4330; ARM-NEXT: bl __aeabi_lmul331; ARM-NEXT: mov r5, r1332; ARM-NEXT: ldr r1, [sp] @ 4-byte Reload333; ARM-NEXT: adds r0, r0, r1334; ARM-NEXT: str r0, [sp] @ 4-byte Spill335; ARM-NEXT: adcs r5, r4336; ARM-NEXT: mov r0, r7337; ARM-NEXT: mov r1, r4338; ARM-NEXT: ldr r6, [sp, #8] @ 4-byte Reload339; ARM-NEXT: mov r2, r6340; ARM-NEXT: mov r3, r4341; ARM-NEXT: bl __aeabi_lmul342; ARM-NEXT: ldr r2, [sp] @ 4-byte Reload343; ARM-NEXT: adds r0, r0, r2344; ARM-NEXT: str r0, [sp] @ 4-byte Spill345; ARM-NEXT: adcs r1, r4346; ARM-NEXT: adds r5, r5, r1347; ARM-NEXT: mov r7, r4348; ARM-NEXT: adcs r7, r4349; ARM-NEXT: ldr r0, [sp, #4] @ 4-byte Reload350; ARM-NEXT: mov r1, r4351; ARM-NEXT: mov r2, r6352; ARM-NEXT: mov r3, r4353; ARM-NEXT: bl __aeabi_lmul354; ARM-NEXT: mov r2, r1355; ARM-NEXT: adds r3, r0, r5356; ARM-NEXT: adcs r2, r7357; ARM-NEXT: mvns r1, r4358; ARM-NEXT: cmp r2, #0359; ARM-NEXT: mov r0, r1360; ARM-NEXT: beq .LBB7_3361; ARM-NEXT: @ %bb.1:362; ARM-NEXT: beq .LBB7_4363; ARM-NEXT: .LBB7_2:364; ARM-NEXT: add sp, #12365; ARM-NEXT: pop {r4, r5, r6, r7, pc}366; ARM-NEXT: .LBB7_3:367; ARM-NEXT: ldr r0, [sp] @ 4-byte Reload368; ARM-NEXT: bne .LBB7_2369; ARM-NEXT: .LBB7_4:370; ARM-NEXT: mov r1, r3371; ARM-NEXT: add sp, #12372; ARM-NEXT: pop {r4, r5, r6, r7, pc}373 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 32)374 ret i64 %tmp375}376 377define i64 @func8(i64 %x, i64 %y) nounwind {378; ARM-LABEL: func8:379; ARM: @ %bb.0:380; ARM-NEXT: .save {r4, r5, r6, r7, lr}381; ARM-NEXT: push {r4, r5, r6, r7, lr}382; ARM-NEXT: .pad #12383; ARM-NEXT: sub sp, #12384; ARM-NEXT: str r3, [sp, #8] @ 4-byte Spill385; ARM-NEXT: mov r5, r2386; ARM-NEXT: mov r6, r1387; ARM-NEXT: str r1, [sp, #4] @ 4-byte Spill388; ARM-NEXT: mov r7, r0389; ARM-NEXT: movs r4, #0390; ARM-NEXT: mov r1, r4391; ARM-NEXT: mov r3, r4392; ARM-NEXT: bl __aeabi_lmul393; ARM-NEXT: str r1, [sp] @ 4-byte Spill394; ARM-NEXT: mov r0, r6395; ARM-NEXT: mov r1, r4396; ARM-NEXT: mov r2, r5397; ARM-NEXT: mov r3, r4398; ARM-NEXT: bl __aeabi_lmul399; ARM-NEXT: mov r5, r1400; ARM-NEXT: ldr r1, [sp] @ 4-byte Reload401; ARM-NEXT: adds r0, r0, r1402; ARM-NEXT: str r0, [sp] @ 4-byte Spill403; ARM-NEXT: adcs r5, r4404; ARM-NEXT: mov r0, r7405; ARM-NEXT: mov r1, r4406; ARM-NEXT: ldr r6, [sp, #8] @ 4-byte Reload407; ARM-NEXT: mov r2, r6408; ARM-NEXT: mov r3, r4409; ARM-NEXT: bl __aeabi_lmul410; ARM-NEXT: ldr r2, [sp] @ 4-byte Reload411; ARM-NEXT: adds r0, r0, r2412; ARM-NEXT: str r0, [sp] @ 4-byte Spill413; ARM-NEXT: adcs r1, r4414; ARM-NEXT: adds r5, r5, r1415; ARM-NEXT: mov r7, r4416; ARM-NEXT: adcs r7, r4417; ARM-NEXT: ldr r0, [sp, #4] @ 4-byte Reload418; ARM-NEXT: mov r1, r4419; ARM-NEXT: mov r2, r6420; ARM-NEXT: mov r3, r4421; ARM-NEXT: bl __aeabi_lmul422; ARM-NEXT: adds r0, r0, r5423; ARM-NEXT: adcs r1, r7424; ARM-NEXT: lsls r1, r1, #1425; ARM-NEXT: lsrs r5, r0, #31426; ARM-NEXT: adds r2, r1, r5427; ARM-NEXT: lsls r0, r0, #1428; ARM-NEXT: ldr r1, [sp] @ 4-byte Reload429; ARM-NEXT: lsrs r1, r1, #31430; ARM-NEXT: adds r3, r0, r1431; ARM-NEXT: mvns r1, r4432; ARM-NEXT: cmp r5, #0433; ARM-NEXT: mov r0, r1434; ARM-NEXT: beq .LBB8_3435; ARM-NEXT: @ %bb.1:436; ARM-NEXT: beq .LBB8_4437; ARM-NEXT: .LBB8_2:438; ARM-NEXT: add sp, #12439; ARM-NEXT: pop {r4, r5, r6, r7, pc}440; ARM-NEXT: .LBB8_3:441; ARM-NEXT: mov r0, r3442; ARM-NEXT: bne .LBB8_2443; ARM-NEXT: .LBB8_4:444; ARM-NEXT: mov r1, r2445; ARM-NEXT: add sp, #12446; ARM-NEXT: pop {r4, r5, r6, r7, pc}447 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 63)448 ret i64 %tmp449}450