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