xref: /llvm-project/llvm/test/CodeGen/X86/apx/imul.ll (revision a9e8a3a18eb897196f88d3705ccd966f5b52c012)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd -verify-machineinstrs | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -verify-machineinstrs | FileCheck --check-prefix=NF %s
4
5define i16 @mul16rr(i16 noundef %a, i16 noundef %b) {
6; CHECK-LABEL: mul16rr:
7; CHECK:       # %bb.0: # %entry
8; CHECK-NEXT:    imull %esi, %edi, %eax
9; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
10; CHECK-NEXT:    retq
11;
12; NF-LABEL: mul16rr:
13; NF:       # %bb.0: # %entry
14; NF-NEXT:    {nf} imull %esi, %edi, %eax
15; NF-NEXT:    # kill: def $ax killed $ax killed $eax
16; NF-NEXT:    retq
17entry:
18  %mul = mul i16 %a, %b
19  ret i16 %mul
20}
21
22define i32 @mul32rr(i32 noundef %a, i32 noundef %b) {
23; CHECK-LABEL: mul32rr:
24; CHECK:       # %bb.0: # %entry
25; CHECK-NEXT:    imull %esi, %edi, %eax
26; CHECK-NEXT:    retq
27;
28; NF-LABEL: mul32rr:
29; NF:       # %bb.0: # %entry
30; NF-NEXT:    {nf} imull %esi, %edi, %eax
31; NF-NEXT:    retq
32entry:
33  %mul = mul i32 %a, %b
34  ret i32 %mul
35}
36
37define i64 @mul64rr(i64 noundef %a, i64 noundef %b) {
38; CHECK-LABEL: mul64rr:
39; CHECK:       # %bb.0: # %entry
40; CHECK-NEXT:    imulq %rsi, %rdi, %rax
41; CHECK-NEXT:    retq
42;
43; NF-LABEL: mul64rr:
44; NF:       # %bb.0: # %entry
45; NF-NEXT:    {nf} imulq %rsi, %rdi, %rax
46; NF-NEXT:    retq
47entry:
48  %mul = mul i64 %a, %b
49  ret i64 %mul
50}
51
52define i16 @smul16rr(i16 noundef %a, i16 noundef %b) {
53; CHECK-LABEL: smul16rr:
54; CHECK:       # %bb.0: # %entry
55; CHECK-NEXT:    imulw %si, %di, %ax
56; CHECK-NEXT:    retq
57;
58; NF-LABEL: smul16rr:
59; NF:       # %bb.0: # %entry
60; NF-NEXT:    {nf} imulw %si, %di, %ax
61; NF-NEXT:    retq
62entry:
63  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
64  %mul = extractvalue {i16, i1} %t, 0
65  ret i16 %mul
66}
67
68define i32 @smul32rr(i32 noundef %a, i32 noundef %b) {
69; CHECK-LABEL: smul32rr:
70; CHECK:       # %bb.0: # %entry
71; CHECK-NEXT:    imull %esi, %edi, %eax
72; CHECK-NEXT:    retq
73;
74; NF-LABEL: smul32rr:
75; NF:       # %bb.0: # %entry
76; NF-NEXT:    {nf} imull %esi, %edi, %eax
77; NF-NEXT:    retq
78entry:
79  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b)
80  %mul = extractvalue {i32, i1} %t, 0
81  ret i32 %mul
82}
83
84define i64 @smul64rr(i64 noundef %a, i64 noundef %b) {
85; CHECK-LABEL: smul64rr:
86; CHECK:       # %bb.0: # %entry
87; CHECK-NEXT:    imulq %rsi, %rdi, %rax
88; CHECK-NEXT:    retq
89;
90; NF-LABEL: smul64rr:
91; NF:       # %bb.0: # %entry
92; NF-NEXT:    {nf} imulq %rsi, %rdi, %rax
93; NF-NEXT:    retq
94entry:
95  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
96  %mul = extractvalue {i64, i1} %t, 0
97  ret i64 %mul
98}
99
100define i16 @mul16rm(i16 noundef %a, ptr %ptr) {
101; CHECK-LABEL: mul16rm:
102; CHECK:       # %bb.0: # %entry
103; CHECK-NEXT:    imulw (%rsi), %di, %ax
104; CHECK-NEXT:    retq
105;
106; NF-LABEL: mul16rm:
107; NF:       # %bb.0: # %entry
108; NF-NEXT:    {nf} imulw (%rsi), %di, %ax
109; NF-NEXT:    retq
110entry:
111  %b = load i16, ptr %ptr
112  %mul = mul i16 %a, %b
113  ret i16 %mul
114}
115
116define i32 @mul32rm(i32 noundef %a, ptr %ptr) {
117; CHECK-LABEL: mul32rm:
118; CHECK:       # %bb.0: # %entry
119; CHECK-NEXT:    imull (%rsi), %edi, %eax
120; CHECK-NEXT:    retq
121;
122; NF-LABEL: mul32rm:
123; NF:       # %bb.0: # %entry
124; NF-NEXT:    {nf} imull (%rsi), %edi, %eax
125; NF-NEXT:    retq
126entry:
127  %b = load i32, ptr %ptr
128  %mul = mul i32 %a, %b
129  ret i32 %mul
130}
131
132define i64 @mul64rm(i64 noundef %a, ptr %ptr) {
133; CHECK-LABEL: mul64rm:
134; CHECK:       # %bb.0: # %entry
135; CHECK-NEXT:    imulq (%rsi), %rdi, %rax
136; CHECK-NEXT:    retq
137;
138; NF-LABEL: mul64rm:
139; NF:       # %bb.0: # %entry
140; NF-NEXT:    {nf} imulq (%rsi), %rdi, %rax
141; NF-NEXT:    retq
142entry:
143  %b = load i64, ptr %ptr
144  %mul = mul i64 %a, %b
145  ret i64 %mul
146}
147
148define i16 @smul16rm(i16 noundef %a, ptr %ptr) {
149; CHECK-LABEL: smul16rm:
150; CHECK:       # %bb.0: # %entry
151; CHECK-NEXT:    imulw (%rsi), %di, %ax
152; CHECK-NEXT:    retq
153;
154; NF-LABEL: smul16rm:
155; NF:       # %bb.0: # %entry
156; NF-NEXT:    {nf} imulw (%rsi), %di, %ax
157; NF-NEXT:    retq
158entry:
159  %b = load i16, ptr %ptr
160  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
161  %mul = extractvalue {i16, i1} %t, 0
162  ret i16 %mul
163}
164
165define i32 @smul32rm(i32 noundef %a, ptr %ptr) {
166; CHECK-LABEL: smul32rm:
167; CHECK:       # %bb.0: # %entry
168; CHECK-NEXT:    imull (%rsi), %edi, %eax
169; CHECK-NEXT:    retq
170;
171; NF-LABEL: smul32rm:
172; NF:       # %bb.0: # %entry
173; NF-NEXT:    {nf} imull (%rsi), %edi, %eax
174; NF-NEXT:    retq
175entry:
176  %b = load i32, ptr %ptr
177  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b)
178  %mul = extractvalue {i32, i1} %t, 0
179  ret i32 %mul
180}
181
182define i64 @smul64rm(i64 noundef %a, ptr %ptr) {
183; CHECK-LABEL: smul64rm:
184; CHECK:       # %bb.0: # %entry
185; CHECK-NEXT:    imulq (%rsi), %rdi, %rax
186; CHECK-NEXT:    retq
187;
188; NF-LABEL: smul64rm:
189; NF:       # %bb.0: # %entry
190; NF-NEXT:    {nf} imulq (%rsi), %rdi, %rax
191; NF-NEXT:    retq
192entry:
193  %b = load i64, ptr %ptr
194  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
195  %mul = extractvalue {i64, i1} %t, 0
196  ret i64 %mul
197}
198
199declare { i16, i1 } @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
200declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
201declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
202