xref: /llvm-project/llvm/test/CodeGen/PowerPC/mul-high.ll (revision a3ada630d8abd00930db1c2822427be2301a489e)
1*a3ada630SAmy Kwan; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2*a3ada630SAmy Kwan; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
3*a3ada630SAmy Kwan; RUN:   -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
4*a3ada630SAmy Kwan; RUN:   FileCheck %s
5*a3ada630SAmy Kwan
6*a3ada630SAmy Kwan; This test case tests multiply high for i32 and i64. When the values are
7*a3ada630SAmy Kwan; sign-extended, mulh[d|w] is emitted. When values are zero-extended,
8*a3ada630SAmy Kwan; mulh[d|w]u is emitted instead.
9*a3ada630SAmy Kwan
10*a3ada630SAmy Kwan; The primary goal is transforming the pattern:
11*a3ada630SAmy Kwan; (shift (mul (ext $a, <wide_type>), (ext $b, <wide_type>)), <narrow_type>)
12*a3ada630SAmy Kwan; into (mulhs $a, $b) for sign extend, and (mulhu $a, $b) for zero extend,
13*a3ada630SAmy Kwan; provided that the mulh operation is legal for <narrow_type>.
14*a3ada630SAmy Kwan; The shift operation can be either the srl or sra operations.
15*a3ada630SAmy Kwan
16*a3ada630SAmy Kwan; When no attribute is present on i32, the shift operation is srl.
17*a3ada630SAmy Kwandefine i32 @test_mulhw(i32 %a, i32 %b) {
18*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhw:
19*a3ada630SAmy Kwan; CHECK:       # %bb.0:
20*a3ada630SAmy Kwan; CHECK-NEXT:    mulhw r3, r3, r4
21*a3ada630SAmy Kwan; CHECK-NEXT:    clrldi r3, r3, 32
22*a3ada630SAmy Kwan; CHECK-NEXT:    blr
23*a3ada630SAmy Kwan  %1 = sext i32 %a to i64
24*a3ada630SAmy Kwan  %2 = sext i32 %b to i64
25*a3ada630SAmy Kwan  %mul = mul i64 %1, %2
26*a3ada630SAmy Kwan  %shr = lshr i64 %mul, 32
27*a3ada630SAmy Kwan  %tr = trunc i64 %shr to i32
28*a3ada630SAmy Kwan  ret i32 %tr
29*a3ada630SAmy Kwan}
30*a3ada630SAmy Kwan
31*a3ada630SAmy Kwandefine i32 @test_mulhu(i32 %a, i32 %b) {
32*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhu:
33*a3ada630SAmy Kwan; CHECK:       # %bb.0:
34*a3ada630SAmy Kwan; CHECK-NEXT:    mulhwu r3, r3, r4
35*a3ada630SAmy Kwan; CHECK-NEXT:    clrldi r3, r3, 32
36*a3ada630SAmy Kwan; CHECK-NEXT:    blr
37*a3ada630SAmy Kwan  %1 = zext i32 %a to i64
38*a3ada630SAmy Kwan  %2 = zext i32 %b to i64
39*a3ada630SAmy Kwan  %mul = mul i64 %1, %2
40*a3ada630SAmy Kwan  %shr = lshr i64 %mul, 32
41*a3ada630SAmy Kwan  %tr = trunc i64 %shr to i32
42*a3ada630SAmy Kwan  ret i32 %tr
43*a3ada630SAmy Kwan}
44*a3ada630SAmy Kwan
45*a3ada630SAmy Kwandefine i64 @test_mulhd(i64 %a, i64 %b) {
46*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhd:
47*a3ada630SAmy Kwan; CHECK:       # %bb.0:
48*a3ada630SAmy Kwan; CHECK-NEXT:    mulhd r3, r3, r4
49*a3ada630SAmy Kwan; CHECK-NEXT:    blr
50*a3ada630SAmy Kwan  %1 = sext i64 %a to i128
51*a3ada630SAmy Kwan  %2 = sext i64 %b to i128
52*a3ada630SAmy Kwan  %mul = mul i128 %1, %2
53*a3ada630SAmy Kwan  %shr = lshr i128 %mul, 64
54*a3ada630SAmy Kwan  %tr = trunc i128 %shr to i64
55*a3ada630SAmy Kwan  ret i64 %tr
56*a3ada630SAmy Kwan}
57*a3ada630SAmy Kwan
58*a3ada630SAmy Kwandefine i64 @test_mulhdu(i64 %a, i64 %b) {
59*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhdu:
60*a3ada630SAmy Kwan; CHECK:       # %bb.0:
61*a3ada630SAmy Kwan; CHECK-NEXT:    mulhdu r3, r3, r4
62*a3ada630SAmy Kwan; CHECK-NEXT:    blr
63*a3ada630SAmy Kwan  %1 = zext i64 %a to i128
64*a3ada630SAmy Kwan  %2 = zext i64 %b to i128
65*a3ada630SAmy Kwan  %mul = mul i128 %1, %2
66*a3ada630SAmy Kwan  %shr = lshr i128 %mul, 64
67*a3ada630SAmy Kwan  %tr = trunc i128 %shr to i64
68*a3ada630SAmy Kwan  ret i64 %tr
69*a3ada630SAmy Kwan}
70*a3ada630SAmy Kwan
71*a3ada630SAmy Kwan; When the signext attribute is present on i32, the shift operation is sra.
72*a3ada630SAmy Kwan; We are actually transforming (sra (mul sext_in_reg, sext_in_reg)) into mulh.
73*a3ada630SAmy Kwandefine signext i32 @test_mulhw_signext(i32 %a, i32 %b) {
74*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhw_signext:
75*a3ada630SAmy Kwan; CHECK:       # %bb.0:
76*a3ada630SAmy Kwan; CHECK-NEXT:    mulhw r3, r3, r4
77*a3ada630SAmy Kwan; CHECK-NEXT:    extsw r3, r3
78*a3ada630SAmy Kwan; CHECK-NEXT:    blr
79*a3ada630SAmy Kwan  %1 = sext i32 %a to i64
80*a3ada630SAmy Kwan  %2 = sext i32 %b to i64
81*a3ada630SAmy Kwan  %mul = mul i64 %1, %2
82*a3ada630SAmy Kwan  %shr = lshr i64 %mul, 32
83*a3ada630SAmy Kwan  %tr = trunc i64 %shr to i32
84*a3ada630SAmy Kwan  ret i32 %tr
85*a3ada630SAmy Kwan}
86*a3ada630SAmy Kwan
87*a3ada630SAmy Kwandefine zeroext i32 @test_mulhu_zeroext(i32 %a, i32 %b) {
88*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhu_zeroext:
89*a3ada630SAmy Kwan; CHECK:       # %bb.0:
90*a3ada630SAmy Kwan; CHECK-NEXT:    mulhwu r3, r3, r4
91*a3ada630SAmy Kwan; CHECK-NEXT:    clrldi r3, r3, 32
92*a3ada630SAmy Kwan; CHECK-NEXT:    blr
93*a3ada630SAmy Kwan  %1 = zext i32 %a to i64
94*a3ada630SAmy Kwan  %2 = zext i32 %b to i64
95*a3ada630SAmy Kwan  %mul = mul i64 %1, %2
96*a3ada630SAmy Kwan  %shr = lshr i64 %mul, 32
97*a3ada630SAmy Kwan  %tr = trunc i64 %shr to i32
98*a3ada630SAmy Kwan  ret i32 %tr
99*a3ada630SAmy Kwan}
100*a3ada630SAmy Kwan
101*a3ada630SAmy Kwandefine signext i64 @test_mulhd_signext(i64 %a, i64 %b) {
102*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhd_signext:
103*a3ada630SAmy Kwan; CHECK:       # %bb.0:
104*a3ada630SAmy Kwan; CHECK-NEXT:    mulhd r3, r3, r4
105*a3ada630SAmy Kwan; CHECK-NEXT:    blr
106*a3ada630SAmy Kwan  %1 = sext i64 %a to i128
107*a3ada630SAmy Kwan  %2 = sext i64 %b to i128
108*a3ada630SAmy Kwan  %mul = mul i128 %1, %2
109*a3ada630SAmy Kwan  %shr = lshr i128 %mul, 64
110*a3ada630SAmy Kwan  %tr = trunc i128 %shr to i64
111*a3ada630SAmy Kwan  ret i64 %tr
112*a3ada630SAmy Kwan}
113*a3ada630SAmy Kwan
114*a3ada630SAmy Kwandefine zeroext i64 @test_mulhdu_zeroext(i64 %a, i64 %b) {
115*a3ada630SAmy Kwan; CHECK-LABEL: test_mulhdu_zeroext:
116*a3ada630SAmy Kwan; CHECK:       # %bb.0:
117*a3ada630SAmy Kwan; CHECK-NEXT:    mulhdu r3, r3, r4
118*a3ada630SAmy Kwan; CHECK-NEXT:    blr
119*a3ada630SAmy Kwan  %1 = zext i64 %a to i128
120*a3ada630SAmy Kwan  %2 = zext i64 %b to i128
121*a3ada630SAmy Kwan  %mul = mul i128 %1, %2
122*a3ada630SAmy Kwan  %shr = lshr i128 %mul, 64
123*a3ada630SAmy Kwan  %tr = trunc i128 %shr to i64
124*a3ada630SAmy Kwan  ret i64 %tr
125*a3ada630SAmy Kwan}
126