xref: /llvm-project/llvm/test/CodeGen/X86/fpenv-combine.ll (revision a21abc782a8e1cb718a10c471a3b634f3102fc1c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s -check-prefix=X64
3
4declare i256 @llvm.get.fpenv.i256()
5declare void @llvm.set.fpenv.i256(i256 %fpenv)
6declare void @llvm.reset.fpenv()
7
8; Cannot fold get_fpenv+load+store because loaded value is used in
9; more than one instruction.
10define void @get_fpenv_02(ptr %ptr1, ptr %ptr2) #0 {
11; X64-LABEL: get_fpenv_02:
12; X64:       # %bb.0:
13; X64-NEXT:    pushq %r14
14; X64-NEXT:    pushq %rbx
15; X64-NEXT:    subq $40, %rsp
16; X64-NEXT:    movq %rsi, %rbx
17; X64-NEXT:    movq %rdi, %r14
18; X64-NEXT:    movq %rsp, %rdi
19; X64-NEXT:    callq fegetenv@PLT
20; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
21; X64-NEXT:    movq (%rsp), %rcx
22; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
23; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rsi
24; X64-NEXT:    movq %rsi, 16(%r14)
25; X64-NEXT:    movq %rcx, (%r14)
26; X64-NEXT:    movq %rax, 24(%r14)
27; X64-NEXT:    movq %rdx, 8(%r14)
28; X64-NEXT:    movq %rsi, 16(%rbx)
29; X64-NEXT:    movq %rcx, (%rbx)
30; X64-NEXT:    movq %rax, 24(%rbx)
31; X64-NEXT:    movq %rdx, 8(%rbx)
32; X64-NEXT:    addq $40, %rsp
33; X64-NEXT:    popq %rbx
34; X64-NEXT:    popq %r14
35; X64-NEXT:    retq
36  %fpenv = call i256 @llvm.get.fpenv.i256()
37  store i256 %fpenv, ptr %ptr1
38  store i256 %fpenv, ptr %ptr2
39  ret void
40}
41
42; Cannot fold get_fpenv+load+store because load and store have different type.
43define void @get_fpenv_03(ptr %ptr) #0 {
44; X64-LABEL: get_fpenv_03:
45; X64:       # %bb.0:
46; X64-NEXT:    pushq %rbx
47; X64-NEXT:    subq $32, %rsp
48; X64-NEXT:    movq %rdi, %rbx
49; X64-NEXT:    movq %rsp, %rdi
50; X64-NEXT:    callq fegetenv@PLT
51; X64-NEXT:    movl (%rsp), %eax
52; X64-NEXT:    movl %eax, (%rbx)
53; X64-NEXT:    addq $32, %rsp
54; X64-NEXT:    popq %rbx
55; X64-NEXT:    retq
56  %fpenv = call i256 @llvm.get.fpenv.i256()
57  %part = trunc i256 %fpenv to i32
58  store i32 %part, ptr %ptr
59  ret void
60}
61
62; Cannot fold get_fpenv+load+store because loaded value is not
63; immediately stored.
64define void @get_fpenv_04(ptr %ptr) #0 {
65; X64-LABEL: get_fpenv_04:
66; X64:       # %bb.0:
67; X64-NEXT:    pushq %rbx
68; X64-NEXT:    subq $32, %rsp
69; X64-NEXT:    movq %rdi, %rbx
70; X64-NEXT:    movq %rsp, %rdi
71; X64-NEXT:    callq fegetenv@PLT
72; X64-NEXT:    movq (%rsp), %rax
73; X64-NEXT:    andl $1, %eax
74; X64-NEXT:    movq %rax, (%rbx)
75; X64-NEXT:    movq $0, 24(%rbx)
76; X64-NEXT:    movq $0, 8(%rbx)
77; X64-NEXT:    movq $0, 16(%rbx)
78; X64-NEXT:    addq $32, %rsp
79; X64-NEXT:    popq %rbx
80; X64-NEXT:    retq
81  %fpenv = call i256 @llvm.get.fpenv.i256()
82  %masked = and i256 %fpenv, 1
83  store i256 %masked, ptr %ptr
84  ret void
85}
86
87; Cannot fold get_fpenv+load+store because there is a memory operation
88; between load and store.
89define void @get_fpenv_05(ptr %ptr1, ptr %ptr2) #0 {
90; X64-LABEL: get_fpenv_05:
91; X64:       # %bb.0:
92; X64-NEXT:    pushq %r14
93; X64-NEXT:    pushq %rbx
94; X64-NEXT:    subq $40, %rsp
95; X64-NEXT:    movq %rsi, %rbx
96; X64-NEXT:    movq %rdi, %r14
97; X64-NEXT:    movq %rsp, %rdi
98; X64-NEXT:    callq fegetenv@PLT
99; X64-NEXT:    movq (%rsp), %rax
100; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
101; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
102; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rsi
103; X64-NEXT:    movl $0, (%r14)
104; X64-NEXT:    movq %rsi, 24(%rbx)
105; X64-NEXT:    movq %rdx, 16(%rbx)
106; X64-NEXT:    movq %rcx, 8(%rbx)
107; X64-NEXT:    movq %rax, (%rbx)
108; X64-NEXT:    addq $40, %rsp
109; X64-NEXT:    popq %rbx
110; X64-NEXT:    popq %r14
111; X64-NEXT:    retq
112  %fpenv = call i256 @llvm.get.fpenv.i256()
113  store i32 0, ptr %ptr1
114  store i256 %fpenv, ptr %ptr2
115  ret void
116}
117
118; Cannot fold load+save+set_fpenv because there is a memory operation
119; between load and store.
120define void @set_fpenv_02(ptr %ptr1, ptr %ptr2) #0 {
121; X64-LABEL: set_fpenv_02:
122; X64:       # %bb.0:
123; X64-NEXT:    subq $40, %rsp
124; X64-NEXT:    movq (%rdi), %rax
125; X64-NEXT:    movq 8(%rdi), %rcx
126; X64-NEXT:    movq 16(%rdi), %rdx
127; X64-NEXT:    movq 24(%rdi), %rdi
128; X64-NEXT:    movl $0, (%rsi)
129; X64-NEXT:    movq %rdi, {{[0-9]+}}(%rsp)
130; X64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
131; X64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
132; X64-NEXT:    movq %rax, (%rsp)
133; X64-NEXT:    movq %rsp, %rdi
134; X64-NEXT:    callq fesetenv@PLT
135; X64-NEXT:    addq $40, %rsp
136; X64-NEXT:    retq
137  %fpenv = load i256, ptr %ptr1
138  store i32 0, ptr %ptr2
139  call void @llvm.set.fpenv.i256(i256 %fpenv)
140  ret void
141}
142
143; Cannot fold load+save+set_fpenv because loaded value is used in
144; more then one store.
145define void @set_fpenv_03(ptr %ptr1, ptr %ptr2) #0 {
146; X64-LABEL: set_fpenv_03:
147; X64:       # %bb.0:
148; X64-NEXT:    pushq %r15
149; X64-NEXT:    pushq %r14
150; X64-NEXT:    pushq %r13
151; X64-NEXT:    pushq %r12
152; X64-NEXT:    pushq %rbx
153; X64-NEXT:    subq $32, %rsp
154; X64-NEXT:    movq %rsi, %rbx
155; X64-NEXT:    movq (%rdi), %r14
156; X64-NEXT:    movq 8(%rdi), %r15
157; X64-NEXT:    movq 16(%rdi), %r12
158; X64-NEXT:    movq 24(%rdi), %r13
159; X64-NEXT:    callq fesetenv@PLT
160; X64-NEXT:    movq %r13, 24(%rbx)
161; X64-NEXT:    movq %r12, 16(%rbx)
162; X64-NEXT:    movq %r15, 8(%rbx)
163; X64-NEXT:    movq %r14, (%rbx)
164; X64-NEXT:    addq $32, %rsp
165; X64-NEXT:    popq %rbx
166; X64-NEXT:    popq %r12
167; X64-NEXT:    popq %r13
168; X64-NEXT:    popq %r14
169; X64-NEXT:    popq %r15
170; X64-NEXT:    retq
171  %fpenv = load i256, ptr %ptr1
172  call void @llvm.set.fpenv.i256(i256 %fpenv)
173  store i256 %fpenv, ptr %ptr2
174  ret void
175}
176
177; Cannot fold load+save+set_fpenv because loaded value is not
178; immediately stored.
179define void @set_fpenv_04(ptr %ptr) #0 {
180; X64-LABEL: set_fpenv_04:
181; X64:       # %bb.0:
182; X64-NEXT:    subq $40, %rsp
183; X64-NEXT:    movq (%rdi), %rax
184; X64-NEXT:    andl $1, %eax
185; X64-NEXT:    movq %rax, (%rsp)
186; X64-NEXT:    movq $0, {{[0-9]+}}(%rsp)
187; X64-NEXT:    movq $0, {{[0-9]+}}(%rsp)
188; X64-NEXT:    movq $0, {{[0-9]+}}(%rsp)
189; X64-NEXT:    movq %rsp, %rdi
190; X64-NEXT:    callq fesetenv@PLT
191; X64-NEXT:    addq $40, %rsp
192; X64-NEXT:    retq
193  %fpenv = load i256, ptr %ptr
194  %masked = and i256 %fpenv, 1
195  call void @llvm.set.fpenv.i256(i256 %masked)
196  ret void
197}
198
199
200attributes #0 = { nounwind "use-soft-float"="true" }
201