201 lines
6 KiB
LLVM
201 lines
6 KiB
LLVM
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||
|
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s -check-prefix=X64
|
||
|
|
||
|
declare i256 @llvm.get.fpenv.i256()
|
||
|
declare void @llvm.set.fpenv.i256(i256 %fpenv)
|
||
|
declare void @llvm.reset.fpenv()
|
||
|
|
||
|
; Cannot fold get_fpenv+load+store because loaded value is used in
|
||
|
; more than one instruction.
|
||
|
define void @get_fpenv_02(ptr %ptr1, ptr %ptr2) #0 {
|
||
|
; X64-LABEL: get_fpenv_02:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: pushq %r14
|
||
|
; X64-NEXT: pushq %rbx
|
||
|
; X64-NEXT: subq $40, %rsp
|
||
|
; X64-NEXT: movq %rsi, %rbx
|
||
|
; X64-NEXT: movq %rdi, %r14
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fegetenv@PLT
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rax
|
||
|
; X64-NEXT: movq (%rsp), %rcx
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rdx
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rsi
|
||
|
; X64-NEXT: movq %rsi, 16(%r14)
|
||
|
; X64-NEXT: movq %rcx, (%r14)
|
||
|
; X64-NEXT: movq %rax, 24(%r14)
|
||
|
; X64-NEXT: movq %rdx, 8(%r14)
|
||
|
; X64-NEXT: movq %rsi, 16(%rbx)
|
||
|
; X64-NEXT: movq %rcx, (%rbx)
|
||
|
; X64-NEXT: movq %rax, 24(%rbx)
|
||
|
; X64-NEXT: movq %rdx, 8(%rbx)
|
||
|
; X64-NEXT: addq $40, %rsp
|
||
|
; X64-NEXT: popq %rbx
|
||
|
; X64-NEXT: popq %r14
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = call i256 @llvm.get.fpenv.i256()
|
||
|
store i256 %fpenv, ptr %ptr1
|
||
|
store i256 %fpenv, ptr %ptr2
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold get_fpenv+load+store because load and store have different type.
|
||
|
define void @get_fpenv_03(ptr %ptr) #0 {
|
||
|
; X64-LABEL: get_fpenv_03:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: pushq %rbx
|
||
|
; X64-NEXT: subq $32, %rsp
|
||
|
; X64-NEXT: movq %rdi, %rbx
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fegetenv@PLT
|
||
|
; X64-NEXT: movl (%rsp), %eax
|
||
|
; X64-NEXT: movl %eax, (%rbx)
|
||
|
; X64-NEXT: addq $32, %rsp
|
||
|
; X64-NEXT: popq %rbx
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = call i256 @llvm.get.fpenv.i256()
|
||
|
%part = trunc i256 %fpenv to i32
|
||
|
store i32 %part, ptr %ptr
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold get_fpenv+load+store because loaded value is not
|
||
|
; immediately stored.
|
||
|
define void @get_fpenv_04(ptr %ptr) #0 {
|
||
|
; X64-LABEL: get_fpenv_04:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: pushq %rbx
|
||
|
; X64-NEXT: subq $32, %rsp
|
||
|
; X64-NEXT: movq %rdi, %rbx
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fegetenv@PLT
|
||
|
; X64-NEXT: movq (%rsp), %rax
|
||
|
; X64-NEXT: andl $1, %eax
|
||
|
; X64-NEXT: movq %rax, (%rbx)
|
||
|
; X64-NEXT: movq $0, 24(%rbx)
|
||
|
; X64-NEXT: movq $0, 8(%rbx)
|
||
|
; X64-NEXT: movq $0, 16(%rbx)
|
||
|
; X64-NEXT: addq $32, %rsp
|
||
|
; X64-NEXT: popq %rbx
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = call i256 @llvm.get.fpenv.i256()
|
||
|
%masked = and i256 %fpenv, 1
|
||
|
store i256 %masked, ptr %ptr
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold get_fpenv+load+store because there is a memory operation
|
||
|
; between load and store.
|
||
|
define void @get_fpenv_05(ptr %ptr1, ptr %ptr2) #0 {
|
||
|
; X64-LABEL: get_fpenv_05:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: pushq %r14
|
||
|
; X64-NEXT: pushq %rbx
|
||
|
; X64-NEXT: subq $40, %rsp
|
||
|
; X64-NEXT: movq %rsi, %rbx
|
||
|
; X64-NEXT: movq %rdi, %r14
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fegetenv@PLT
|
||
|
; X64-NEXT: movq (%rsp), %rax
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rcx
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rdx
|
||
|
; X64-NEXT: movq {{[0-9]+}}(%rsp), %rsi
|
||
|
; X64-NEXT: movl $0, (%r14)
|
||
|
; X64-NEXT: movq %rsi, 24(%rbx)
|
||
|
; X64-NEXT: movq %rdx, 16(%rbx)
|
||
|
; X64-NEXT: movq %rcx, 8(%rbx)
|
||
|
; X64-NEXT: movq %rax, (%rbx)
|
||
|
; X64-NEXT: addq $40, %rsp
|
||
|
; X64-NEXT: popq %rbx
|
||
|
; X64-NEXT: popq %r14
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = call i256 @llvm.get.fpenv.i256()
|
||
|
store i32 0, ptr %ptr1
|
||
|
store i256 %fpenv, ptr %ptr2
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold load+save+set_fpenv because there is a memory operation
|
||
|
; between load and store.
|
||
|
define void @set_fpenv_02(ptr %ptr1, ptr %ptr2) #0 {
|
||
|
; X64-LABEL: set_fpenv_02:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: subq $40, %rsp
|
||
|
; X64-NEXT: movq (%rdi), %rax
|
||
|
; X64-NEXT: movq 8(%rdi), %rcx
|
||
|
; X64-NEXT: movq 16(%rdi), %rdx
|
||
|
; X64-NEXT: movq 24(%rdi), %rdi
|
||
|
; X64-NEXT: movl $0, (%rsi)
|
||
|
; X64-NEXT: movq %rdi, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq %rcx, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq %rax, (%rsp)
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fesetenv@PLT
|
||
|
; X64-NEXT: addq $40, %rsp
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = load i256, ptr %ptr1
|
||
|
store i32 0, ptr %ptr2
|
||
|
call void @llvm.set.fpenv.i256(i256 %fpenv)
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold load+save+set_fpenv because loaded value is used in
|
||
|
; more then one store.
|
||
|
define void @set_fpenv_03(ptr %ptr1, ptr %ptr2) #0 {
|
||
|
; X64-LABEL: set_fpenv_03:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: pushq %r15
|
||
|
; X64-NEXT: pushq %r14
|
||
|
; X64-NEXT: pushq %r13
|
||
|
; X64-NEXT: pushq %r12
|
||
|
; X64-NEXT: pushq %rbx
|
||
|
; X64-NEXT: subq $32, %rsp
|
||
|
; X64-NEXT: movq %rsi, %rbx
|
||
|
; X64-NEXT: movq (%rdi), %r14
|
||
|
; X64-NEXT: movq 8(%rdi), %r15
|
||
|
; X64-NEXT: movq 16(%rdi), %r12
|
||
|
; X64-NEXT: movq 24(%rdi), %r13
|
||
|
; X64-NEXT: callq fesetenv@PLT
|
||
|
; X64-NEXT: movq %r13, 24(%rbx)
|
||
|
; X64-NEXT: movq %r12, 16(%rbx)
|
||
|
; X64-NEXT: movq %r15, 8(%rbx)
|
||
|
; X64-NEXT: movq %r14, (%rbx)
|
||
|
; X64-NEXT: addq $32, %rsp
|
||
|
; X64-NEXT: popq %rbx
|
||
|
; X64-NEXT: popq %r12
|
||
|
; X64-NEXT: popq %r13
|
||
|
; X64-NEXT: popq %r14
|
||
|
; X64-NEXT: popq %r15
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = load i256, ptr %ptr1
|
||
|
call void @llvm.set.fpenv.i256(i256 %fpenv)
|
||
|
store i256 %fpenv, ptr %ptr2
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
; Cannot fold load+save+set_fpenv because loaded value is not
|
||
|
; immediately stored.
|
||
|
define void @set_fpenv_04(ptr %ptr) #0 {
|
||
|
; X64-LABEL: set_fpenv_04:
|
||
|
; X64: # %bb.0:
|
||
|
; X64-NEXT: subq $40, %rsp
|
||
|
; X64-NEXT: movq (%rdi), %rax
|
||
|
; X64-NEXT: andl $1, %eax
|
||
|
; X64-NEXT: movq %rax, (%rsp)
|
||
|
; X64-NEXT: movq $0, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq $0, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq $0, {{[0-9]+}}(%rsp)
|
||
|
; X64-NEXT: movq %rsp, %rdi
|
||
|
; X64-NEXT: callq fesetenv@PLT
|
||
|
; X64-NEXT: addq $40, %rsp
|
||
|
; X64-NEXT: retq
|
||
|
%fpenv = load i256, ptr %ptr
|
||
|
%masked = and i256 %fpenv, 1
|
||
|
call void @llvm.set.fpenv.i256(i256 %masked)
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
|
||
|
attributes #0 = { nounwind "use-soft-float"="true" }
|