371 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-sse -verify-machineinstrs < %s | FileCheck %s --check-prefixes=X86,SDAG-X863; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-sse2 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=X86,SDAG-X864; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefixes=X64,SDAG-X645; RUN: llc -mtriple=i686-unknown-linux-gnu -global-isel=1 -global-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=X86,GISEL-X866; RUN: llc -mtriple=x86_64-unknown-linux-gnu -global-isel=1 -global-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=X64,GISEL-X647 8declare i32 @llvm.get.rounding()9 10define i32 @test_flt_rounds() nounwind {11; X86-LABEL: test_flt_rounds:12; X86: # %bb.0:13; X86-NEXT: subl $2, %esp14; X86-NEXT: fnstcw (%esp)15; X86-NEXT: movzwl (%esp), %ecx16; X86-NEXT: shrl $9, %ecx17; X86-NEXT: andb $6, %cl18; X86-NEXT: movl $45, %eax19; X86-NEXT: # kill: def $cl killed $cl killed $ecx20; X86-NEXT: shrl %cl, %eax21; X86-NEXT: andl $3, %eax22; X86-NEXT: addl $2, %esp23; X86-NEXT: retl24;25; X64-LABEL: test_flt_rounds:26; X64: # %bb.0:27; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)28; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %ecx29; X64-NEXT: shrl $9, %ecx30; X64-NEXT: andb $6, %cl31; X64-NEXT: movl $45, %eax32; X64-NEXT: # kill: def $cl killed $cl killed $ecx33; X64-NEXT: shrl %cl, %eax34; X64-NEXT: andl $3, %eax35; X64-NEXT: retq36 %1 = call i32 @llvm.get.rounding()37 ret i32 %138}39 40; Make sure we preserve order with fesetround.41define i32 @multiple_flt_rounds() nounwind {42; SDAG-X86-LABEL: multiple_flt_rounds:43; SDAG-X86: # %bb.0: # %entry44; SDAG-X86-NEXT: pushl %ebx45; SDAG-X86-NEXT: pushl %esi46; SDAG-X86-NEXT: subl $20, %esp47; SDAG-X86-NEXT: movl $1024, (%esp) # imm = 0x40048; SDAG-X86-NEXT: calll fesetround49; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)50; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx51; SDAG-X86-NEXT: shrl $9, %ecx52; SDAG-X86-NEXT: andb $6, %cl53; SDAG-X86-NEXT: movl $45, %esi54; SDAG-X86-NEXT: movl $45, %eax55; SDAG-X86-NEXT: # kill: def $cl killed $cl killed $ecx56; SDAG-X86-NEXT: shrl %cl, %eax57; SDAG-X86-NEXT: andl $3, %eax58; SDAG-X86-NEXT: xorl %ebx, %ebx59; SDAG-X86-NEXT: cmpl $3, %eax60; SDAG-X86-NEXT: setne %bl61; SDAG-X86-NEXT: movl $0, (%esp)62; SDAG-X86-NEXT: calll fesetround63; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)64; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx65; SDAG-X86-NEXT: shrl $9, %ecx66; SDAG-X86-NEXT: andb $6, %cl67; SDAG-X86-NEXT: movl $45, %eax68; SDAG-X86-NEXT: # kill: def $cl killed $cl killed $ecx69; SDAG-X86-NEXT: shrl %cl, %eax70; SDAG-X86-NEXT: andl $3, %eax71; SDAG-X86-NEXT: cmpl $1, %eax72; SDAG-X86-NEXT: je .LBB1_273; SDAG-X86-NEXT: # %bb.1: # %entry74; SDAG-X86-NEXT: incl %ebx75; SDAG-X86-NEXT: .LBB1_2: # %entry76; SDAG-X86-NEXT: movl $3072, (%esp) # imm = 0xC0077; SDAG-X86-NEXT: calll fesetround78; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)79; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx80; SDAG-X86-NEXT: shrl $9, %ecx81; SDAG-X86-NEXT: andb $6, %cl82; SDAG-X86-NEXT: movl $45, %eax83; SDAG-X86-NEXT: # kill: def $cl killed $cl killed $ecx84; SDAG-X86-NEXT: shrl %cl, %eax85; SDAG-X86-NEXT: andl $3, %eax86; SDAG-X86-NEXT: cmpl $1, %eax87; SDAG-X86-NEXT: sbbl $-1, %ebx88; SDAG-X86-NEXT: movl $2048, (%esp) # imm = 0x80089; SDAG-X86-NEXT: calll fesetround90; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)91; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx92; SDAG-X86-NEXT: shrl $9, %ecx93; SDAG-X86-NEXT: andb $6, %cl94; SDAG-X86-NEXT: # kill: def $cl killed $cl killed $ecx95; SDAG-X86-NEXT: shrl %cl, %esi96; SDAG-X86-NEXT: andl $3, %esi97; SDAG-X86-NEXT: xorl %ecx, %ecx98; SDAG-X86-NEXT: cmpl $2, %esi99; SDAG-X86-NEXT: setne %cl100; SDAG-X86-NEXT: negl %ecx101; SDAG-X86-NEXT: xorl %eax, %eax102; SDAG-X86-NEXT: cmpl %ecx, %ebx103; SDAG-X86-NEXT: setne %al104; SDAG-X86-NEXT: addl $20, %esp105; SDAG-X86-NEXT: popl %esi106; SDAG-X86-NEXT: popl %ebx107; SDAG-X86-NEXT: retl108;109; SDAG-X64-LABEL: multiple_flt_rounds:110; SDAG-X64: # %bb.0: # %entry111; SDAG-X64-NEXT: pushq %rbp112; SDAG-X64-NEXT: pushq %r14113; SDAG-X64-NEXT: pushq %rbx114; SDAG-X64-NEXT: subq $16, %rsp115; SDAG-X64-NEXT: movl $1024, %edi # imm = 0x400116; SDAG-X64-NEXT: callq fesetround117; SDAG-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)118; SDAG-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx119; SDAG-X64-NEXT: shrl $9, %ecx120; SDAG-X64-NEXT: andb $6, %cl121; SDAG-X64-NEXT: movl $45, %ebx122; SDAG-X64-NEXT: movl $45, %eax123; SDAG-X64-NEXT: # kill: def $cl killed $cl killed $ecx124; SDAG-X64-NEXT: shrl %cl, %eax125; SDAG-X64-NEXT: andl $3, %eax126; SDAG-X64-NEXT: xorl %r14d, %r14d127; SDAG-X64-NEXT: cmpl $3, %eax128; SDAG-X64-NEXT: setne %r14b129; SDAG-X64-NEXT: xorl %edi, %edi130; SDAG-X64-NEXT: callq fesetround131; SDAG-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)132; SDAG-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx133; SDAG-X64-NEXT: shrl $9, %ecx134; SDAG-X64-NEXT: andb $6, %cl135; SDAG-X64-NEXT: movl $45, %eax136; SDAG-X64-NEXT: # kill: def $cl killed $cl killed $ecx137; SDAG-X64-NEXT: shrl %cl, %eax138; SDAG-X64-NEXT: andl $3, %eax139; SDAG-X64-NEXT: leal 1(%r14), %ebp140; SDAG-X64-NEXT: cmpl $1, %eax141; SDAG-X64-NEXT: cmovel %r14d, %ebp142; SDAG-X64-NEXT: movl $3072, %edi # imm = 0xC00143; SDAG-X64-NEXT: callq fesetround144; SDAG-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)145; SDAG-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx146; SDAG-X64-NEXT: shrl $9, %ecx147; SDAG-X64-NEXT: andb $6, %cl148; SDAG-X64-NEXT: movl $45, %eax149; SDAG-X64-NEXT: # kill: def $cl killed $cl killed $ecx150; SDAG-X64-NEXT: shrl %cl, %eax151; SDAG-X64-NEXT: andl $3, %eax152; SDAG-X64-NEXT: cmpl $1, %eax153; SDAG-X64-NEXT: sbbl $-1, %ebp154; SDAG-X64-NEXT: movl $2048, %edi # imm = 0x800155; SDAG-X64-NEXT: callq fesetround156; SDAG-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)157; SDAG-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx158; SDAG-X64-NEXT: shrl $9, %ecx159; SDAG-X64-NEXT: andb $6, %cl160; SDAG-X64-NEXT: # kill: def $cl killed $cl killed $ecx161; SDAG-X64-NEXT: shrl %cl, %ebx162; SDAG-X64-NEXT: andl $3, %ebx163; SDAG-X64-NEXT: xorl %ecx, %ecx164; SDAG-X64-NEXT: cmpl $2, %ebx165; SDAG-X64-NEXT: setne %cl166; SDAG-X64-NEXT: negl %ecx167; SDAG-X64-NEXT: xorl %eax, %eax168; SDAG-X64-NEXT: cmpl %ecx, %ebp169; SDAG-X64-NEXT: setne %al170; SDAG-X64-NEXT: addq $16, %rsp171; SDAG-X64-NEXT: popq %rbx172; SDAG-X64-NEXT: popq %r14173; SDAG-X64-NEXT: popq %rbp174; SDAG-X64-NEXT: retq175;176; GISEL-X86-LABEL: multiple_flt_rounds:177; GISEL-X86: # %bb.0: # %entry178; GISEL-X86-NEXT: pushl %ebp179; GISEL-X86-NEXT: pushl %ebx180; GISEL-X86-NEXT: pushl %edi181; GISEL-X86-NEXT: pushl %esi182; GISEL-X86-NEXT: subl $12, %esp183; GISEL-X86-NEXT: movl $1, %ebp184; GISEL-X86-NEXT: movl $1024, (%esp) # imm = 0x400185; GISEL-X86-NEXT: calll fesetround186; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)187; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx188; GISEL-X86-NEXT: shrl $9, %ecx189; GISEL-X86-NEXT: andb $6, %cl190; GISEL-X86-NEXT: movl $45, %edi191; GISEL-X86-NEXT: movl $45, %eax192; GISEL-X86-NEXT: # kill: def $cl killed $cl killed $ecx193; GISEL-X86-NEXT: shrl %cl, %eax194; GISEL-X86-NEXT: andl $3, %eax195; GISEL-X86-NEXT: xorl %ebx, %ebx196; GISEL-X86-NEXT: cmpl $3, %eax197; GISEL-X86-NEXT: setne %bl198; GISEL-X86-NEXT: andl $1, %ebx199; GISEL-X86-NEXT: movl $0, (%esp)200; GISEL-X86-NEXT: calll fesetround201; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)202; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx203; GISEL-X86-NEXT: shrl $9, %ecx204; GISEL-X86-NEXT: andb $6, %cl205; GISEL-X86-NEXT: movl $45, %edx206; GISEL-X86-NEXT: # kill: def $cl killed $cl killed $ecx207; GISEL-X86-NEXT: shrl %cl, %edx208; GISEL-X86-NEXT: andl $3, %edx209; GISEL-X86-NEXT: xorl %eax, %eax210; GISEL-X86-NEXT: cmpl $1, %edx211; GISEL-X86-NEXT: sete %cl212; GISEL-X86-NEXT: testl %ebx, %ebx213; GISEL-X86-NEXT: je .LBB1_2214; GISEL-X86-NEXT: # %bb.1: # %entry215; GISEL-X86-NEXT: movl $2, %ebp216; GISEL-X86-NEXT: .LBB1_2: # %entry217; GISEL-X86-NEXT: xorl %esi, %esi218; GISEL-X86-NEXT: movb %cl, %al219; GISEL-X86-NEXT: andl $1, %eax220; GISEL-X86-NEXT: je .LBB1_4221; GISEL-X86-NEXT: # %bb.3: # %entry222; GISEL-X86-NEXT: movl %ebx, %ebp223; GISEL-X86-NEXT: .LBB1_4: # %entry224; GISEL-X86-NEXT: movl $3072, (%esp) # imm = 0xC00225; GISEL-X86-NEXT: calll fesetround226; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)227; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx228; GISEL-X86-NEXT: shrl $9, %ecx229; GISEL-X86-NEXT: andb $6, %cl230; GISEL-X86-NEXT: movl $45, %eax231; GISEL-X86-NEXT: # kill: def $cl killed $cl killed $ecx232; GISEL-X86-NEXT: shrl %cl, %eax233; GISEL-X86-NEXT: andl $3, %eax234; GISEL-X86-NEXT: xorl %ebx, %ebx235; GISEL-X86-NEXT: cmpl %esi, %eax236; GISEL-X86-NEXT: setne %bl237; GISEL-X86-NEXT: andl $1, %ebx238; GISEL-X86-NEXT: addl %ebp, %ebx239; GISEL-X86-NEXT: movl $2048, (%esp) # imm = 0x800240; GISEL-X86-NEXT: calll fesetround241; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)242; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx243; GISEL-X86-NEXT: shrl $9, %ecx244; GISEL-X86-NEXT: andb $6, %cl245; GISEL-X86-NEXT: # kill: def $cl killed $cl killed $ecx246; GISEL-X86-NEXT: shrl %cl, %edi247; GISEL-X86-NEXT: andl $3, %edi248; GISEL-X86-NEXT: xorl %ecx, %ecx249; GISEL-X86-NEXT: movl $2, %eax250; GISEL-X86-NEXT: cmpl %eax, %edi251; GISEL-X86-NEXT: setne %cl252; GISEL-X86-NEXT: shll $31, %ecx253; GISEL-X86-NEXT: sarl $31, %ecx254; GISEL-X86-NEXT: xorl %eax, %eax255; GISEL-X86-NEXT: cmpl %ecx, %ebx256; GISEL-X86-NEXT: setne %al257; GISEL-X86-NEXT: andl $1, %eax258; GISEL-X86-NEXT: addl $12, %esp259; GISEL-X86-NEXT: popl %esi260; GISEL-X86-NEXT: popl %edi261; GISEL-X86-NEXT: popl %ebx262; GISEL-X86-NEXT: popl %ebp263; GISEL-X86-NEXT: retl264;265; GISEL-X64-LABEL: multiple_flt_rounds:266; GISEL-X64: # %bb.0: # %entry267; GISEL-X64-NEXT: pushq %rbp268; GISEL-X64-NEXT: pushq %r15269; GISEL-X64-NEXT: pushq %r14270; GISEL-X64-NEXT: pushq %rbx271; GISEL-X64-NEXT: pushq %rax272; GISEL-X64-NEXT: movl $1, %r14d273; GISEL-X64-NEXT: movl $2, %ebp274; GISEL-X64-NEXT: movl $1024, %edi # imm = 0x400275; GISEL-X64-NEXT: callq fesetround276; GISEL-X64-NEXT: fnstcw (%rsp)277; GISEL-X64-NEXT: movzwl (%rsp), %ecx278; GISEL-X64-NEXT: shrl $9, %ecx279; GISEL-X64-NEXT: andb $6, %cl280; GISEL-X64-NEXT: movl $45, %ebx281; GISEL-X64-NEXT: movl $45, %eax282; GISEL-X64-NEXT: # kill: def $cl killed $cl killed $ecx283; GISEL-X64-NEXT: shrl %cl, %eax284; GISEL-X64-NEXT: andl $3, %eax285; GISEL-X64-NEXT: xorl %r15d, %r15d286; GISEL-X64-NEXT: cmpl $3, %eax287; GISEL-X64-NEXT: setne %r15b288; GISEL-X64-NEXT: andl $1, %r15d289; GISEL-X64-NEXT: xorl %edi, %edi290; GISEL-X64-NEXT: callq fesetround291; GISEL-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)292; GISEL-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx293; GISEL-X64-NEXT: shrl $9, %ecx294; GISEL-X64-NEXT: andb $6, %cl295; GISEL-X64-NEXT: movl $45, %eax296; GISEL-X64-NEXT: # kill: def $cl killed $cl killed $ecx297; GISEL-X64-NEXT: shrl %cl, %eax298; GISEL-X64-NEXT: andl $3, %eax299; GISEL-X64-NEXT: xorl %ecx, %ecx300; GISEL-X64-NEXT: cmpl $1, %eax301; GISEL-X64-NEXT: sete %cl302; GISEL-X64-NEXT: testl %r15d, %r15d303; GISEL-X64-NEXT: cmovel %r14d, %ebp304; GISEL-X64-NEXT: andl $1, %ecx305; GISEL-X64-NEXT: cmovnel %r15d, %ebp306; GISEL-X64-NEXT: movl $3072, %edi # imm = 0xC00307; GISEL-X64-NEXT: callq fesetround308; GISEL-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)309; GISEL-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx310; GISEL-X64-NEXT: shrl $9, %ecx311; GISEL-X64-NEXT: andb $6, %cl312; GISEL-X64-NEXT: movl $45, %eax313; GISEL-X64-NEXT: # kill: def $cl killed $cl killed $ecx314; GISEL-X64-NEXT: shrl %cl, %eax315; GISEL-X64-NEXT: andl $3, %eax316; GISEL-X64-NEXT: xorl %r14d, %r14d317; GISEL-X64-NEXT: cmpl $0, %eax318; GISEL-X64-NEXT: setne %r14b319; GISEL-X64-NEXT: andl $1, %r14d320; GISEL-X64-NEXT: addl %ebp, %r14d321; GISEL-X64-NEXT: movl $2048, %edi # imm = 0x800322; GISEL-X64-NEXT: callq fesetround323; GISEL-X64-NEXT: fnstcw {{[0-9]+}}(%rsp)324; GISEL-X64-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx325; GISEL-X64-NEXT: shrl $9, %ecx326; GISEL-X64-NEXT: andb $6, %cl327; GISEL-X64-NEXT: # kill: def $cl killed $cl killed $ecx328; GISEL-X64-NEXT: shrl %cl, %ebx329; GISEL-X64-NEXT: andl $3, %ebx330; GISEL-X64-NEXT: xorl %ecx, %ecx331; GISEL-X64-NEXT: cmpl $2, %ebx332; GISEL-X64-NEXT: setne %cl333; GISEL-X64-NEXT: shll $31, %ecx334; GISEL-X64-NEXT: sarl $31, %ecx335; GISEL-X64-NEXT: xorl %eax, %eax336; GISEL-X64-NEXT: cmpl %ecx, %r14d337; GISEL-X64-NEXT: setne %al338; GISEL-X64-NEXT: andl $1, %eax339; GISEL-X64-NEXT: addq $8, %rsp340; GISEL-X64-NEXT: popq %rbx341; GISEL-X64-NEXT: popq %r14342; GISEL-X64-NEXT: popq %r15343; GISEL-X64-NEXT: popq %rbp344; GISEL-X64-NEXT: retq345entry:346 %call = tail call i32 @fesetround(i32 1024)347 %0 = tail call i32 @llvm.get.rounding()348 %cmp = icmp ne i32 %0, 3349 %spec.select = zext i1 %cmp to i32350 %call1 = tail call i32 @fesetround(i32 0)351 %1 = tail call i32 @llvm.get.rounding()352 %cmp2 = icmp eq i32 %1, 1353 %inc4 = select i1 %cmp, i32 2, i32 1354 %errs.1 = select i1 %cmp2, i32 %spec.select, i32 %inc4355 %call6 = tail call i32 @fesetround(i32 3072)356 %2 = tail call i32 @llvm.get.rounding()357 %cmp7 = icmp ne i32 %2, 0358 %inc9 = zext i1 %cmp7 to i32359 %spec.select22 = add nuw nsw i32 %errs.1, %inc9360 %call11 = tail call i32 @fesetround(i32 2048)361 %3 = tail call i32 @llvm.get.rounding()362 %cmp12 = icmp ne i32 %3, 2363 %inc14.neg = sext i1 %cmp12 to i32364 %cmp16 = icmp ne i32 %spec.select22, %inc14.neg365 %cond = zext i1 %cmp16 to i32366 ret i32 %cond367}368 369; Function Attrs: nounwind370declare dso_local i32 @fesetround(i32) local_unnamed_addr #1371