xref: /llvm-project/llvm/test/CodeGen/X86/shift_minsize.ll (revision faa0e2ae7644c332180cfe4e19daf378bc7a46a9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown       | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64--windows-msvc | FileCheck %s -check-prefix=CHECK-WIN
4
5; The Windows runtime doesn't have these.
6; CHECK-WIN-NOT: __ashlti3
7; CHECK-WIN-NOT: __ashrti3
8; CHECK-WIN-NOT: __lshrti3
9
10define i64 @f0(i64 %val, i64 %amt) minsize optsize {
11; CHECK-LABEL: f0:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    movq %rsi, %rcx
14; CHECK-NEXT:    movq %rdi, %rax
15; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
16; CHECK-NEXT:    shlq %cl, %rax
17; CHECK-NEXT:    retq
18;
19; CHECK-WIN-LABEL: f0:
20; CHECK-WIN:       # %bb.0:
21; CHECK-WIN-NEXT:    movq %rcx, %rax
22; CHECK-WIN-NEXT:    movl %edx, %ecx
23; CHECK-WIN-NEXT:    shlq %cl, %rax
24; CHECK-WIN-NEXT:    retq
25  %res = shl i64 %val, %amt
26  ret i64 %res
27}
28
29define i32 @f1(i64 %x, i64 %y) minsize optsize {
30; CHECK-LABEL: f1:
31; CHECK:       # %bb.0:
32; CHECK-NEXT:    movq %rsi, %rcx
33; CHECK-NEXT:    movq %rdi, %rax
34; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
35; CHECK-NEXT:    shlq %cl, %rax
36; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
37; CHECK-NEXT:    retq
38;
39; CHECK-WIN-LABEL: f1:
40; CHECK-WIN:       # %bb.0:
41; CHECK-WIN-NEXT:    movq %rcx, %rax
42; CHECK-WIN-NEXT:    movl %edx, %ecx
43; CHECK-WIN-NEXT:    shlq %cl, %rax
44; CHECK-WIN-NEXT:    # kill: def $eax killed $eax killed $rax
45; CHECK-WIN-NEXT:    retq
46	%a = shl i64 %x, %y
47	%b = trunc i64 %a to i32
48	ret i32 %b
49}
50
51define i32 @f2(i64 %x, i64 %y) minsize optsize {
52; CHECK-LABEL: f2:
53; CHECK:       # %bb.0:
54; CHECK-NEXT:    movq %rsi, %rcx
55; CHECK-NEXT:    movq %rdi, %rax
56; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
57; CHECK-NEXT:    sarq %cl, %rax
58; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
59; CHECK-NEXT:    retq
60;
61; CHECK-WIN-LABEL: f2:
62; CHECK-WIN:       # %bb.0:
63; CHECK-WIN-NEXT:    movq %rcx, %rax
64; CHECK-WIN-NEXT:    movl %edx, %ecx
65; CHECK-WIN-NEXT:    sarq %cl, %rax
66; CHECK-WIN-NEXT:    # kill: def $eax killed $eax killed $rax
67; CHECK-WIN-NEXT:    retq
68	%a = ashr i64 %x, %y
69	%b = trunc i64 %a to i32
70	ret i32 %b
71}
72
73define i32 @f3(i64 %x, i64 %y) minsize optsize {
74; CHECK-LABEL: f3:
75; CHECK:       # %bb.0:
76; CHECK-NEXT:    movq %rsi, %rcx
77; CHECK-NEXT:    movq %rdi, %rax
78; CHECK-NEXT:    # kill: def $cl killed $cl killed $rcx
79; CHECK-NEXT:    shrq %cl, %rax
80; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
81; CHECK-NEXT:    retq
82;
83; CHECK-WIN-LABEL: f3:
84; CHECK-WIN:       # %bb.0:
85; CHECK-WIN-NEXT:    movq %rcx, %rax
86; CHECK-WIN-NEXT:    movl %edx, %ecx
87; CHECK-WIN-NEXT:    shrq %cl, %rax
88; CHECK-WIN-NEXT:    # kill: def $eax killed $eax killed $rax
89; CHECK-WIN-NEXT:    retq
90	%a = lshr i64 %x, %y
91	%b = trunc i64 %a to i32
92	ret i32 %b
93}
94
95define dso_local { i64, i64 } @shl128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
96; CHECK-LABEL: shl128:
97; CHECK:       # %bb.0: # %entry
98; CHECK-NEXT:    pushq %rax
99; CHECK-NEXT:    .cfi_def_cfa_offset 16
100; CHECK-NEXT:    movzbl %dl, %edx
101; CHECK-NEXT:    callq __ashlti3@PLT
102; CHECK-NEXT:    popq %rcx
103; CHECK-NEXT:    .cfi_def_cfa_offset 8
104; CHECK-NEXT:    retq
105;
106; CHECK-WIN-LABEL: shl128:
107; CHECK-WIN:       # %bb.0: # %entry
108; CHECK-WIN-NEXT:    movq %rcx, %r9
109; CHECK-WIN-NEXT:    movl %r8d, %ecx
110; CHECK-WIN-NEXT:    shldq %cl, %r9, %rdx
111; CHECK-WIN-NEXT:    shlq %cl, %r9
112; CHECK-WIN-NEXT:    xorl %eax, %eax
113; CHECK-WIN-NEXT:    testb $64, %r8b
114; CHECK-WIN-NEXT:    cmovneq %r9, %rdx
115; CHECK-WIN-NEXT:    cmoveq %r9, %rax
116; CHECK-WIN-NEXT:    retq
117entry:
118  %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
119  %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
120  %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
121  %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
122  %conv = sext i8 %y to i32
123  %sh_prom = zext i32 %conv to i128
124  %shl = shl i128 %x.sroa.0.0.insert.insert, %sh_prom
125  %retval.sroa.0.0.extract.trunc = trunc i128 %shl to i64
126  %retval.sroa.2.0.extract.shift = lshr i128 %shl, 64
127  %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
128  %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
129  %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
130  ret { i64, i64 } %.fca.1.insert
131}
132
133define dso_local { i64, i64 } @ashr128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
134; CHECK-LABEL: ashr128:
135; CHECK:       # %bb.0: # %entry
136; CHECK-NEXT:    pushq %rax
137; CHECK-NEXT:    .cfi_def_cfa_offset 16
138; CHECK-NEXT:    movzbl %dl, %edx
139; CHECK-NEXT:    callq __ashrti3@PLT
140; CHECK-NEXT:    popq %rcx
141; CHECK-NEXT:    .cfi_def_cfa_offset 8
142; CHECK-NEXT:    retq
143;
144; CHECK-WIN-LABEL: ashr128:
145; CHECK-WIN:       # %bb.0: # %entry
146; CHECK-WIN-NEXT:    movq %rcx, %rax
147; CHECK-WIN-NEXT:    movl %r8d, %ecx
148; CHECK-WIN-NEXT:    shrdq %cl, %rdx, %rax
149; CHECK-WIN-NEXT:    movq %rdx, %r9
150; CHECK-WIN-NEXT:    sarq %cl, %r9
151; CHECK-WIN-NEXT:    sarq $63, %rdx
152; CHECK-WIN-NEXT:    testb $64, %r8b
153; CHECK-WIN-NEXT:    cmovneq %r9, %rax
154; CHECK-WIN-NEXT:    cmoveq %r9, %rdx
155; CHECK-WIN-NEXT:    retq
156entry:
157  %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
158  %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
159  %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
160  %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
161  %conv = sext i8 %y to i32
162  %sh_prom = zext i32 %conv to i128
163  %shr = ashr i128 %x.sroa.0.0.insert.insert, %sh_prom
164  %retval.sroa.0.0.extract.trunc = trunc i128 %shr to i64
165  %retval.sroa.2.0.extract.shift = lshr i128 %shr, 64
166  %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
167  %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
168  %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
169  ret { i64, i64 } %.fca.1.insert
170}
171
172define dso_local { i64, i64 } @lshr128(i64 %x.coerce0, i64 %x.coerce1, i8 signext %y) minsize optsize {
173; CHECK-LABEL: lshr128:
174; CHECK:       # %bb.0: # %entry
175; CHECK-NEXT:    pushq %rax
176; CHECK-NEXT:    .cfi_def_cfa_offset 16
177; CHECK-NEXT:    movzbl %dl, %edx
178; CHECK-NEXT:    callq __lshrti3@PLT
179; CHECK-NEXT:    popq %rcx
180; CHECK-NEXT:    .cfi_def_cfa_offset 8
181; CHECK-NEXT:    retq
182;
183; CHECK-WIN-LABEL: lshr128:
184; CHECK-WIN:       # %bb.0: # %entry
185; CHECK-WIN-NEXT:    movq %rcx, %rax
186; CHECK-WIN-NEXT:    movl %r8d, %ecx
187; CHECK-WIN-NEXT:    shrdq %cl, %rdx, %rax
188; CHECK-WIN-NEXT:    shrq %cl, %rdx
189; CHECK-WIN-NEXT:    xorl %ecx, %ecx
190; CHECK-WIN-NEXT:    testb $64, %r8b
191; CHECK-WIN-NEXT:    cmovneq %rdx, %rax
192; CHECK-WIN-NEXT:    cmovneq %rcx, %rdx
193; CHECK-WIN-NEXT:    retq
194entry:
195  %x.sroa.2.0.insert.ext = zext i64 %x.coerce1 to i128
196  %x.sroa.2.0.insert.shift = shl nuw i128 %x.sroa.2.0.insert.ext, 64
197  %x.sroa.0.0.insert.ext = zext i64 %x.coerce0 to i128
198  %x.sroa.0.0.insert.insert = or i128 %x.sroa.2.0.insert.shift, %x.sroa.0.0.insert.ext
199  %conv = sext i8 %y to i32
200  %sh_prom = zext i32 %conv to i128
201  %shr = lshr i128 %x.sroa.0.0.insert.insert, %sh_prom
202  %retval.sroa.0.0.extract.trunc = trunc i128 %shr to i64
203  %retval.sroa.2.0.extract.shift = lshr i128 %shr, 64
204  %retval.sroa.2.0.extract.trunc = trunc i128 %retval.sroa.2.0.extract.shift to i64
205  %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %retval.sroa.0.0.extract.trunc, 0
206  %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.sroa.2.0.extract.trunc, 1
207  ret { i64, i64 } %.fca.1.insert
208}
209
210