207 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s3 4define i32 @func(i32 %x, i32 %y) nounwind {5; CHECK-LABEL: func:6; CHECK: // %bb.0:7; CHECK-NEXT: umull x8, w0, w18; CHECK-NEXT: lsr x9, x8, #329; CHECK-NEXT: extr w8, w9, w8, #210; CHECK-NEXT: cmp w9, #311; CHECK-NEXT: csinv w0, w8, wzr, ls12; CHECK-NEXT: ret13 %tmp = call i32 @llvm.umul.fix.sat.i32(i32 %x, i32 %y, i32 2)14 ret i32 %tmp15}16 17define i64 @func2(i64 %x, i64 %y) nounwind {18; CHECK-LABEL: func2:19; CHECK: // %bb.0:20; CHECK-NEXT: mul x8, x0, x121; CHECK-NEXT: umulh x9, x0, x122; CHECK-NEXT: extr x8, x9, x8, #223; CHECK-NEXT: cmp x9, #324; CHECK-NEXT: csinv x0, x8, xzr, ls25; CHECK-NEXT: ret26 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 2)27 ret i64 %tmp28}29 30define i4 @func3(i4 %x, i4 %y) nounwind {31; CHECK-LABEL: func3:32; CHECK: // %bb.0:33; CHECK-NEXT: lsl w8, w0, #2834; CHECK-NEXT: and w9, w1, #0xf35; CHECK-NEXT: umull x8, w8, w936; CHECK-NEXT: lsr x9, x8, #3237; CHECK-NEXT: extr w8, w9, w8, #238; CHECK-NEXT: cmp w9, #339; CHECK-NEXT: csinv w8, w8, wzr, ls40; CHECK-NEXT: lsr w0, w8, #2841; CHECK-NEXT: ret42 %tmp = call i4 @llvm.umul.fix.sat.i4(i4 %x, i4 %y, i32 2)43 ret i4 %tmp44}45 46;; These result in regular integer multiplication with a saturation check.47define i32 @func4(i32 %x, i32 %y) nounwind {48; CHECK-LABEL: func4:49; CHECK: // %bb.0:50; CHECK-NEXT: umull x8, w0, w151; CHECK-NEXT: tst x8, #0xffffffff0000000052; CHECK-NEXT: csinv w0, w8, wzr, eq53; CHECK-NEXT: ret54 %tmp = call i32 @llvm.umul.fix.sat.i32(i32 %x, i32 %y, i32 0)55 ret i32 %tmp56}57 58define i64 @func5(i64 %x, i64 %y) {59; CHECK-LABEL: func5:60; CHECK: // %bb.0:61; CHECK-NEXT: umulh x8, x0, x162; CHECK-NEXT: mul x9, x0, x163; CHECK-NEXT: cmp xzr, x864; CHECK-NEXT: csinv x0, x9, xzr, eq65; CHECK-NEXT: ret66 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 0)67 ret i64 %tmp68}69 70define i4 @func6(i4 %x, i4 %y) nounwind {71; CHECK-LABEL: func6:72; CHECK: // %bb.0:73; CHECK-NEXT: lsl w8, w0, #2874; CHECK-NEXT: and w9, w1, #0xf75; CHECK-NEXT: umull x8, w8, w976; CHECK-NEXT: tst x8, #0xffffffff0000000077; CHECK-NEXT: csinv w8, w8, wzr, eq78; CHECK-NEXT: lsr w0, w8, #2879; CHECK-NEXT: ret80 %tmp = call i4 @llvm.umul.fix.sat.i4(i4 %x, i4 %y, i32 0)81 ret i4 %tmp82}83 84define <2 x i32> @vec(<2 x i32> %x, <2 x i32> %y) nounwind {85; CHECK-LABEL: vec:86; CHECK: // %bb.0:87; CHECK-NEXT: // kill: def $d1 killed $d1 def $q188; CHECK-NEXT: // kill: def $d0 killed $d0 def $q089; CHECK-NEXT: mov w8, v1.s[1]90; CHECK-NEXT: mov w9, v0.s[1]91; CHECK-NEXT: fmov w10, s092; CHECK-NEXT: umull x8, w9, w893; CHECK-NEXT: fmov w9, s194; CHECK-NEXT: umull x9, w10, w995; CHECK-NEXT: tst x8, #0xffffffff0000000096; CHECK-NEXT: csinv w8, w8, wzr, eq97; CHECK-NEXT: tst x9, #0xffffffff0000000098; CHECK-NEXT: csinv w9, w9, wzr, eq99; CHECK-NEXT: fmov s0, w9100; CHECK-NEXT: mov v0.s[1], w8101; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0102; CHECK-NEXT: ret103 %tmp = call <2 x i32> @llvm.umul.fix.sat.v2i32(<2 x i32> %x, <2 x i32> %y, i32 0)104 ret <2 x i32> %tmp105}106 107define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {108; CHECK-LABEL: vec2:109; CHECK: // %bb.0:110; CHECK-NEXT: mov w8, v1.s[1]111; CHECK-NEXT: mov w9, v0.s[1]112; CHECK-NEXT: fmov w10, s0113; CHECK-NEXT: mov w11, v0.s[2]114; CHECK-NEXT: mov w13, v0.s[3]115; CHECK-NEXT: mov w12, v1.s[3]116; CHECK-NEXT: umull x8, w9, w8117; CHECK-NEXT: fmov w9, s1118; CHECK-NEXT: umull x9, w10, w9119; CHECK-NEXT: tst x8, #0xffffffff00000000120; CHECK-NEXT: mov w10, v1.s[2]121; CHECK-NEXT: csinv w8, w8, wzr, eq122; CHECK-NEXT: tst x9, #0xffffffff00000000123; CHECK-NEXT: csinv w9, w9, wzr, eq124; CHECK-NEXT: fmov s0, w9125; CHECK-NEXT: umull x9, w11, w10126; CHECK-NEXT: mov v0.s[1], w8127; CHECK-NEXT: tst x9, #0xffffffff00000000128; CHECK-NEXT: csinv w8, w9, wzr, eq129; CHECK-NEXT: umull x9, w13, w12130; CHECK-NEXT: mov v0.s[2], w8131; CHECK-NEXT: tst x9, #0xffffffff00000000132; CHECK-NEXT: csinv w8, w9, wzr, eq133; CHECK-NEXT: mov v0.s[3], w8134; CHECK-NEXT: ret135 %tmp = call <4 x i32> @llvm.umul.fix.sat.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0)136 ret <4 x i32> %tmp137}138 139define <4 x i64> @vec3(<4 x i64> %x, <4 x i64> %y) nounwind {140; CHECK-LABEL: vec3:141; CHECK: // %bb.0:142; CHECK-NEXT: mov x8, v2.d[1]143; CHECK-NEXT: mov x9, v0.d[1]144; CHECK-NEXT: mov x14, v3.d[1]145; CHECK-NEXT: mov x15, v1.d[1]146; CHECK-NEXT: fmov x10, d2147; CHECK-NEXT: fmov x11, d0148; CHECK-NEXT: mul x12, x11, x10149; CHECK-NEXT: mul x13, x9, x8150; CHECK-NEXT: umulh x8, x9, x8151; CHECK-NEXT: umulh x9, x11, x10152; CHECK-NEXT: mul x10, x15, x14153; CHECK-NEXT: extr x13, x8, x13, #32154; CHECK-NEXT: umulh x11, x15, x14155; CHECK-NEXT: fmov x14, d3156; CHECK-NEXT: fmov x15, d1157; CHECK-NEXT: mul x16, x15, x14158; CHECK-NEXT: umulh x14, x15, x14159; CHECK-NEXT: mov w15, #-1 // =0xffffffff160; CHECK-NEXT: cmp x8, x15161; CHECK-NEXT: extr x8, x9, x12, #32162; CHECK-NEXT: csinv x12, x13, xzr, ls163; CHECK-NEXT: cmp x9, x15164; CHECK-NEXT: extr x9, x11, x10, #32165; CHECK-NEXT: csinv x8, x8, xzr, ls166; CHECK-NEXT: cmp x11, x15167; CHECK-NEXT: csinv x9, x9, xzr, ls168; CHECK-NEXT: fmov d0, x8169; CHECK-NEXT: extr x10, x14, x16, #32170; CHECK-NEXT: cmp x14, x15171; CHECK-NEXT: csinv x10, x10, xzr, ls172; CHECK-NEXT: mov v0.d[1], x12173; CHECK-NEXT: fmov d1, x10174; CHECK-NEXT: mov v1.d[1], x9175; CHECK-NEXT: ret176 %tmp = call <4 x i64> @llvm.umul.fix.sat.v4i64(<4 x i64> %x, <4 x i64> %y, i32 32)177 ret <4 x i64> %tmp178}179 180define i64 @func7(i64 %x, i64 %y) nounwind {181; CHECK-LABEL: func7:182; CHECK: // %bb.0:183; CHECK-NEXT: mul x9, x0, x1184; CHECK-NEXT: mov w8, #-1 // =0xffffffff185; CHECK-NEXT: umulh x10, x0, x1186; CHECK-NEXT: extr x9, x10, x9, #32187; CHECK-NEXT: cmp x10, x8188; CHECK-NEXT: csinv x0, x9, xzr, ls189; CHECK-NEXT: ret190 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 32)191 ret i64 %tmp192}193 194define i64 @func8(i64 %x, i64 %y) nounwind {195; CHECK-LABEL: func8:196; CHECK: // %bb.0:197; CHECK-NEXT: mul x9, x0, x1198; CHECK-NEXT: mov x8, #9223372036854775807 // =0x7fffffffffffffff199; CHECK-NEXT: umulh x10, x0, x1200; CHECK-NEXT: extr x9, x10, x9, #63201; CHECK-NEXT: cmp x10, x8202; CHECK-NEXT: csinv x0, x9, xzr, ls203; CHECK-NEXT: ret204 %tmp = call i64 @llvm.umul.fix.sat.i64(i64 %x, i64 %y, i32 63)205 ret i64 %tmp206}207