1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-sse -verify-machineinstrs < %s | FileCheck %s --check-prefix=X86 3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-sse2 -verify-machineinstrs < %s | FileCheck %s --check-prefix=X86 4; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=X64 5 6declare i32 @llvm.flt.rounds() 7 8define i32 @test_flt_rounds() nounwind { 9; X86-LABEL: test_flt_rounds: 10; X86: # %bb.0: 11; X86-NEXT: subl $2, %esp 12; X86-NEXT: fnstcw (%esp) 13; X86-NEXT: movzwl (%esp), %ecx 14; X86-NEXT: shrl $9, %ecx 15; X86-NEXT: andb $6, %cl 16; X86-NEXT: movl $45, %eax 17; X86-NEXT: # kill: def $cl killed $cl killed $ecx 18; X86-NEXT: shrl %cl, %eax 19; X86-NEXT: andl $3, %eax 20; X86-NEXT: addl $2, %esp 21; X86-NEXT: retl 22; 23; X64-LABEL: test_flt_rounds: 24; X64: # %bb.0: 25; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) 26; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %ecx 27; X64-NEXT: shrl $9, %ecx 28; X64-NEXT: andb $6, %cl 29; X64-NEXT: movl $45, %eax 30; X64-NEXT: # kill: def $cl killed $cl killed $ecx 31; X64-NEXT: shrl %cl, %eax 32; X64-NEXT: andl $3, %eax 33; X64-NEXT: retq 34 %1 = call i32 @llvm.flt.rounds() 35 ret i32 %1 36} 37 38; Make sure we preserve order with fesetround. 39define i32 @multiple_flt_rounds() nounwind { 40; X86-LABEL: multiple_flt_rounds: 41; X86: # %bb.0: # %entry 42; X86-NEXT: pushl %ebx 43; X86-NEXT: pushl %esi 44; X86-NEXT: subl $20, %esp 45; X86-NEXT: movl $1024, (%esp) # imm = 0x400 46; X86-NEXT: calll fesetround 47; X86-NEXT: fnstcw {{[0-9]+}}(%esp) 48; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 49; X86-NEXT: shrl $9, %ecx 50; X86-NEXT: andb $6, %cl 51; X86-NEXT: movl $45, %esi 52; X86-NEXT: movl $45, %eax 53; X86-NEXT: # kill: def $cl killed $cl killed $ecx 54; X86-NEXT: shrl %cl, %eax 55; X86-NEXT: andl $3, %eax 56; X86-NEXT: xorl %ebx, %ebx 57; X86-NEXT: cmpl $3, %eax 58; X86-NEXT: setne %bl 59; X86-NEXT: movl $0, (%esp) 60; X86-NEXT: calll fesetround 61; X86-NEXT: fnstcw {{[0-9]+}}(%esp) 62; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 63; X86-NEXT: shrl $9, %ecx 64; X86-NEXT: andb $6, %cl 65; X86-NEXT: movl $45, %eax 66; X86-NEXT: # kill: def $cl killed $cl killed $ecx 67; X86-NEXT: shrl %cl, %eax 68; X86-NEXT: andl $3, %eax 69; X86-NEXT: cmpl $1, %eax 70; X86-NEXT: je .LBB1_2 71; X86-NEXT: # %bb.1: # %entry 72; X86-NEXT: incl %ebx 73; X86-NEXT: .LBB1_2: # %entry 74; X86-NEXT: movl $3072, (%esp) # imm = 0xC00 75; X86-NEXT: calll fesetround 76; X86-NEXT: fnstcw {{[0-9]+}}(%esp) 77; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 78; X86-NEXT: shrl $9, %ecx 79; X86-NEXT: andb $6, %cl 80; X86-NEXT: movl $45, %eax 81; X86-NEXT: # kill: def $cl killed $cl killed $ecx 82; X86-NEXT: shrl %cl, %eax 83; X86-NEXT: andl $3, %eax 84; X86-NEXT: cmpl $1, %eax 85; X86-NEXT: sbbl $-1, %ebx 86; X86-NEXT: movl $2048, (%esp) # imm = 0x800 87; X86-NEXT: calll fesetround 88; X86-NEXT: fnstcw {{[0-9]+}}(%esp) 89; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 90; X86-NEXT: shrl $9, %ecx 91; X86-NEXT: andb $6, %cl 92; X86-NEXT: # kill: def $cl killed $cl killed $ecx 93; X86-NEXT: shrl %cl, %esi 94; X86-NEXT: andl $3, %esi 95; X86-NEXT: xorl %ecx, %ecx 96; X86-NEXT: cmpl $2, %esi 97; X86-NEXT: setne %cl 98; X86-NEXT: negl %ecx 99; X86-NEXT: xorl %eax, %eax 100; X86-NEXT: cmpl %ecx, %ebx 101; X86-NEXT: setne %al 102; X86-NEXT: addl $20, %esp 103; X86-NEXT: popl %esi 104; X86-NEXT: popl %ebx 105; X86-NEXT: retl 106; 107; X64-LABEL: multiple_flt_rounds: 108; X64: # %bb.0: # %entry 109; X64-NEXT: pushq %rbp 110; X64-NEXT: pushq %r14 111; X64-NEXT: pushq %rbx 112; X64-NEXT: subq $16, %rsp 113; X64-NEXT: movl $1024, %edi # imm = 0x400 114; X64-NEXT: callq fesetround 115; X64-NEXT: fnstcw {{[0-9]+}}(%rsp) 116; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx 117; X64-NEXT: shrl $9, %ecx 118; X64-NEXT: andb $6, %cl 119; X64-NEXT: movl $45, %r14d 120; X64-NEXT: movl $45, %eax 121; X64-NEXT: # kill: def $cl killed $cl killed $ecx 122; X64-NEXT: shrl %cl, %eax 123; X64-NEXT: andl $3, %eax 124; X64-NEXT: xorl %ebx, %ebx 125; X64-NEXT: cmpl $3, %eax 126; X64-NEXT: setne %bl 127; X64-NEXT: xorl %edi, %edi 128; X64-NEXT: callq fesetround 129; X64-NEXT: fnstcw {{[0-9]+}}(%rsp) 130; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx 131; X64-NEXT: shrl $9, %ecx 132; X64-NEXT: andb $6, %cl 133; X64-NEXT: movl $45, %eax 134; X64-NEXT: # kill: def $cl killed $cl killed $ecx 135; X64-NEXT: shrl %cl, %eax 136; X64-NEXT: andl $3, %eax 137; X64-NEXT: leal 1(%rbx), %ebp 138; X64-NEXT: cmpl $1, %eax 139; X64-NEXT: cmovel %ebx, %ebp 140; X64-NEXT: movl $3072, %edi # imm = 0xC00 141; X64-NEXT: callq fesetround 142; X64-NEXT: fnstcw {{[0-9]+}}(%rsp) 143; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx 144; X64-NEXT: shrl $9, %ecx 145; X64-NEXT: andb $6, %cl 146; X64-NEXT: movl $45, %eax 147; X64-NEXT: # kill: def $cl killed $cl killed $ecx 148; X64-NEXT: shrl %cl, %eax 149; X64-NEXT: andl $3, %eax 150; X64-NEXT: cmpl $1, %eax 151; X64-NEXT: sbbl $-1, %ebp 152; X64-NEXT: movl $2048, %edi # imm = 0x800 153; X64-NEXT: callq fesetround 154; X64-NEXT: fnstcw {{[0-9]+}}(%rsp) 155; X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx 156; X64-NEXT: shrl $9, %ecx 157; X64-NEXT: andb $6, %cl 158; X64-NEXT: # kill: def $cl killed $cl killed $ecx 159; X64-NEXT: shrl %cl, %r14d 160; X64-NEXT: andl $3, %r14d 161; X64-NEXT: xorl %ecx, %ecx 162; X64-NEXT: cmpl $2, %r14d 163; X64-NEXT: setne %cl 164; X64-NEXT: negl %ecx 165; X64-NEXT: xorl %eax, %eax 166; X64-NEXT: cmpl %ecx, %ebp 167; X64-NEXT: setne %al 168; X64-NEXT: addq $16, %rsp 169; X64-NEXT: popq %rbx 170; X64-NEXT: popq %r14 171; X64-NEXT: popq %rbp 172; X64-NEXT: retq 173entry: 174 %call = tail call i32 @fesetround(i32 1024) 175 %0 = tail call i32 @llvm.flt.rounds() 176 %cmp = icmp ne i32 %0, 3 177 %spec.select = zext i1 %cmp to i32 178 %call1 = tail call i32 @fesetround(i32 0) 179 %1 = tail call i32 @llvm.flt.rounds() 180 %cmp2 = icmp eq i32 %1, 1 181 %inc4 = select i1 %cmp, i32 2, i32 1 182 %errs.1 = select i1 %cmp2, i32 %spec.select, i32 %inc4 183 %call6 = tail call i32 @fesetround(i32 3072) 184 %2 = tail call i32 @llvm.flt.rounds() 185 %cmp7 = icmp ne i32 %2, 0 186 %inc9 = zext i1 %cmp7 to i32 187 %spec.select22 = add nuw nsw i32 %errs.1, %inc9 188 %call11 = tail call i32 @fesetround(i32 2048) 189 %3 = tail call i32 @llvm.flt.rounds() 190 %cmp12 = icmp ne i32 %3, 2 191 %inc14.neg = sext i1 %cmp12 to i32 192 %cmp16 = icmp ne i32 %spec.select22, %inc14.neg 193 %cond = zext i1 %cmp16 to i32 194 ret i32 %cond 195} 196 197; Function Attrs: nounwind 198declare dso_local i32 @fesetround(i32) local_unnamed_addr #1 199