[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / fpenv-combine.ll
blobd1be4a5f44cf26f6b4b8ffa3bd8c76aef051295c
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
4 declare i256 @llvm.get.fpenv.i256()
5 declare void @llvm.set.fpenv.i256(i256 %fpenv)
6 declare void @llvm.reset.fpenv()
8 ; Cannot fold get_fpenv+load+store because loaded value is used in
9 ; more than one instruction.
10 define 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
42 ; Cannot fold get_fpenv+load+store because load and store have different type.
43 define 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
62 ; Cannot fold get_fpenv+load+store because loaded value is not
63 ; immediately stored.
64 define 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
87 ; Cannot fold get_fpenv+load+store because there is a memory operation
88 ; between load and store.
89 define 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
118 ; Cannot fold load+save+set_fpenv because there is a memory operation
119 ; between load and store.
120 define 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
143 ; Cannot fold load+save+set_fpenv because loaded value is used in
144 ; more then one store.
145 define 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
177 ; Cannot fold load+save+set_fpenv because loaded value is not
178 ; immediately stored.
179 define 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
200 attributes #0 = { nounwind "use-soft-float"="true" }