| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r6 < %s | FileCheck %s --check-prefix=R6-O32 | |
| ; RUN: llc -mtriple=mips64el-linux-gnu -mcpu=mips64r6 < %s | FileCheck %s --check-prefix=R6-N64 | |
| ; RUN: llc -mtriple=mips64el-linux-gnu -mcpu=mips64r2 < %s | FileCheck %s --check-prefix=R2 | |
| ; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r6 -mattr=+micromips < %s | FileCheck %s --check-prefix=MMR6 | |
| define float @rint_f32(float %x) { | |
| ; R6-O32-LABEL: rint_f32: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: rint.s $f0, $f12 | |
| ; | |
| ; R6-N64-LABEL: rint_f32: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: rint.s $f0, $f12 | |
| ; | |
| ; R2-LABEL: rint_f32: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal rintf | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: rint_f32: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc rintf | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call float @llvm.rint.f32(float %x) | |
| ret float %r | |
| } | |
| define double @rint_f64(double %x) { | |
| ; R6-O32-LABEL: rint_f64: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: rint.d $f0, $f12 | |
| ; | |
| ; R6-N64-LABEL: rint_f64: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: rint.d $f0, $f12 | |
| ; | |
| ; R2-LABEL: rint_f64: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal rint | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: rint_f64: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc rint | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call double @llvm.rint.f64(double %x) | |
| ret double %r | |
| } | |
| ; nearbyint must not raise inexact, so it cannot use rint.fmt. | |
| define float @nearbyint_f32(float %x) { | |
| ; R6-O32-LABEL: nearbyint_f32: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: addiu $sp, $sp, -24 | |
| ; R6-O32-NEXT: .cfi_def_cfa_offset 24 | |
| ; R6-O32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; R6-O32-NEXT: .cfi_offset 31, -4 | |
| ; R6-O32-NEXT: balc nearbyintf | |
| ; R6-O32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: addiu $sp, $sp, 24 | |
| ; | |
| ; R6-N64-LABEL: nearbyint_f32: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: daddiu $sp, $sp, -16 | |
| ; R6-N64-NEXT: .cfi_def_cfa_offset 16 | |
| ; R6-N64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R6-N64-NEXT: .cfi_offset 31, -8 | |
| ; R6-N64-NEXT: balc nearbyintf | |
| ; R6-N64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; R2-LABEL: nearbyint_f32: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal nearbyintf | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: nearbyint_f32: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc nearbyintf | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call float @llvm.nearbyint.f32(float %x) | |
| ret float %r | |
| } | |
| define double @nearbyint_f64(double %x) { | |
| ; R6-O32-LABEL: nearbyint_f64: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: addiu $sp, $sp, -24 | |
| ; R6-O32-NEXT: .cfi_def_cfa_offset 24 | |
| ; R6-O32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; R6-O32-NEXT: .cfi_offset 31, -4 | |
| ; R6-O32-NEXT: balc nearbyint | |
| ; R6-O32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: addiu $sp, $sp, 24 | |
| ; | |
| ; R6-N64-LABEL: nearbyint_f64: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: daddiu $sp, $sp, -16 | |
| ; R6-N64-NEXT: .cfi_def_cfa_offset 16 | |
| ; R6-N64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R6-N64-NEXT: .cfi_offset 31, -8 | |
| ; R6-N64-NEXT: balc nearbyint | |
| ; R6-N64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; R2-LABEL: nearbyint_f64: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal nearbyint | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: nearbyint_f64: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc nearbyint | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call double @llvm.nearbyint.f64(double %x) | |
| ret double %r | |
| } | |
| define float @strict_rint_f32(float %x) #0 { | |
| ; R6-O32-LABEL: strict_rint_f32: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: rint.s $f0, $f12 | |
| ; | |
| ; R6-N64-LABEL: strict_rint_f32: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: rint.s $f0, $f12 | |
| ; | |
| ; R2-LABEL: strict_rint_f32: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal rintf | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: strict_rint_f32: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc rintf | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call float @llvm.experimental.constrained.rint.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 | |
| ret float %r | |
| } | |
| define double @strict_rint_f64(double %x) #0 { | |
| ; R6-O32-LABEL: strict_rint_f64: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: rint.d $f0, $f12 | |
| ; | |
| ; R6-N64-LABEL: strict_rint_f64: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: rint.d $f0, $f12 | |
| ; | |
| ; R2-LABEL: strict_rint_f64: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: jal rint | |
| ; R2-NEXT: nop | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: strict_rint_f64: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: balc rint | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %r = call double @llvm.experimental.constrained.rint.f64(double %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 | |
| ret double %r | |
| } | |
| ; Strict rint must stay ordered relative to the volatile store. | |
| define float @strict_rint_order_f32(float %x, ptr %p) #0 { | |
| ; R6-O32-LABEL: strict_rint_order_f32: | |
| ; R6-O32: # %bb.0: | |
| ; R6-O32-NEXT: rint.s $f0, $f12 | |
| ; R6-O32-NEXT: swc1 $f0, 0($5) | |
| ; R6-O32-NEXT: jr $ra | |
| ; R6-O32-NEXT: rint.s $f0, $f0 | |
| ; | |
| ; R6-N64-LABEL: strict_rint_order_f32: | |
| ; R6-N64: # %bb.0: | |
| ; R6-N64-NEXT: rint.s $f0, $f12 | |
| ; R6-N64-NEXT: swc1 $f0, 0($5) | |
| ; R6-N64-NEXT: jr $ra | |
| ; R6-N64-NEXT: rint.s $f0, $f0 | |
| ; | |
| ; R2-LABEL: strict_rint_order_f32: | |
| ; R2: # %bb.0: | |
| ; R2-NEXT: daddiu $sp, $sp, -16 | |
| ; R2-NEXT: .cfi_def_cfa_offset 16 | |
| ; R2-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: sd $16, 0($sp) # 8-byte Folded Spill | |
| ; R2-NEXT: .cfi_offset 31, -8 | |
| ; R2-NEXT: .cfi_offset 16, -16 | |
| ; R2-NEXT: jal rintf | |
| ; R2-NEXT: move $16, $5 | |
| ; R2-NEXT: swc1 $f0, 0($16) | |
| ; R2-NEXT: jal rintf | |
| ; R2-NEXT: mov.s $f12, $f0 | |
| ; R2-NEXT: ld $16, 0($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload | |
| ; R2-NEXT: jr $ra | |
| ; R2-NEXT: daddiu $sp, $sp, 16 | |
| ; | |
| ; MMR6-LABEL: strict_rint_order_f32: | |
| ; MMR6: # %bb.0: | |
| ; MMR6-NEXT: addiu $sp, $sp, -24 | |
| ; MMR6-NEXT: .cfi_def_cfa_offset 24 | |
| ; MMR6-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: sw $16, 16($sp) # 4-byte Folded Spill | |
| ; MMR6-NEXT: .cfi_offset 31, -4 | |
| ; MMR6-NEXT: .cfi_offset 16, -8 | |
| ; MMR6-NEXT: move $16, $5 | |
| ; MMR6-NEXT: balc rintf | |
| ; MMR6-NEXT: swc1 $f0, 0($16) | |
| ; MMR6-NEXT: mov.s $f12, $f0 | |
| ; MMR6-NEXT: balc rintf | |
| ; MMR6-NEXT: lw $16, 16($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload | |
| ; MMR6-NEXT: addiu $sp, $sp, 24 | |
| ; MMR6-NEXT: jrc $ra | |
| %a = call float @llvm.experimental.constrained.rint.f32(float %x, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 | |
| store volatile float %a, ptr %p | |
| %b = call float @llvm.experimental.constrained.rint.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 | |
| ret float %b | |
| } | |
| attributes #0 = { strictfp } |