AMDGPU has native instructions and target intrinsics for this, but these really should be subject to legalization and generic optimizations. This will enable legalization of f16->f32 on targets without f16 support. Implement a somewhat horrible inline expansion for targets without libcall support. This could be better if we could introduce control flow (GlobalISel version not yet implemented). Support for strictfp legalization is less complete but works for the simple cases.
173 lines
6.0 KiB
LLVM
173 lines
6.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: llc -mtriple=mips-- -mattr=+soft-float < %s | FileCheck -check-prefix=SOFT %s
|
|
|
|
define float @ldexp_f32(i8 zeroext %x) {
|
|
; SOFT-LABEL: ldexp_f32:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -24
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 24
|
|
; SOFT-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: move $5, $4
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: lui $4, 16256
|
|
; SOFT-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 24
|
|
%zext = zext i8 %x to i32
|
|
%ldexp = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 %zext)
|
|
ret float %ldexp
|
|
}
|
|
|
|
define double @ldexp_f64(i8 zeroext %x) {
|
|
; SOFT-LABEL: ldexp_f64:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -24
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 24
|
|
; SOFT-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: move $6, $4
|
|
; SOFT-NEXT: lui $4, 16368
|
|
; SOFT-NEXT: jal ldexp
|
|
; SOFT-NEXT: addiu $5, $zero, 0
|
|
; SOFT-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 24
|
|
%zext = zext i8 %x to i32
|
|
%ldexp = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 %zext)
|
|
ret double %ldexp
|
|
}
|
|
|
|
define <2 x float> @ldexp_v2f32(<2 x float> %val, <2 x i32> %exp) {
|
|
; SOFT-LABEL: ldexp_v2f32:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -32
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 32
|
|
; SOFT-NEXT: sw $ra, 28($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $17, 24($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $16, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: .cfi_offset 17, -8
|
|
; SOFT-NEXT: .cfi_offset 16, -12
|
|
; SOFT-NEXT: move $16, $6
|
|
; SOFT-NEXT: move $17, $4
|
|
; SOFT-NEXT: lw $5, 52($sp)
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $4, $7
|
|
; SOFT-NEXT: lw $5, 48($sp)
|
|
; SOFT-NEXT: sw $2, 4($17)
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $4, $16
|
|
; SOFT-NEXT: sw $2, 0($17)
|
|
; SOFT-NEXT: lw $16, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $17, 24($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $ra, 28($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 32
|
|
%1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp)
|
|
ret <2 x float> %1
|
|
}
|
|
|
|
define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) {
|
|
; SOFT-LABEL: ldexp_v4f32:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -40
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 40
|
|
; SOFT-NEXT: sw $ra, 36($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $20, 32($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $19, 28($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $18, 24($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $17, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $16, 16($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: .cfi_offset 20, -8
|
|
; SOFT-NEXT: .cfi_offset 19, -12
|
|
; SOFT-NEXT: .cfi_offset 18, -16
|
|
; SOFT-NEXT: .cfi_offset 17, -20
|
|
; SOFT-NEXT: .cfi_offset 16, -24
|
|
; SOFT-NEXT: move $16, $7
|
|
; SOFT-NEXT: move $18, $4
|
|
; SOFT-NEXT: lw $4, 60($sp)
|
|
; SOFT-NEXT: lw $5, 76($sp)
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $17, $6
|
|
; SOFT-NEXT: lw $19, 64($sp)
|
|
; SOFT-NEXT: lw $20, 68($sp)
|
|
; SOFT-NEXT: lw $5, 72($sp)
|
|
; SOFT-NEXT: lw $4, 56($sp)
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: sw $2, 12($18)
|
|
; SOFT-NEXT: sw $2, 8($18)
|
|
; SOFT-NEXT: move $4, $16
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $5, $20
|
|
; SOFT-NEXT: sw $2, 4($18)
|
|
; SOFT-NEXT: move $4, $17
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $5, $19
|
|
; SOFT-NEXT: sw $2, 0($18)
|
|
; SOFT-NEXT: lw $16, 16($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $17, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $18, 24($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $19, 28($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $20, 32($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $ra, 36($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 40
|
|
%1 = call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> %val, <4 x i32> %exp)
|
|
ret <4 x float> %1
|
|
}
|
|
|
|
define half @ldexp_f16(half %arg0, i32 %arg1) {
|
|
; SOFT-LABEL: ldexp_f16:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -24
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 24
|
|
; SOFT-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: sw $16, 16($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: .cfi_offset 16, -8
|
|
; SOFT-NEXT: move $16, $5
|
|
; SOFT-NEXT: jal __gnu_h2f_ieee
|
|
; SOFT-NEXT: andi $4, $4, 65535
|
|
; SOFT-NEXT: move $4, $2
|
|
; SOFT-NEXT: jal ldexpf
|
|
; SOFT-NEXT: move $5, $16
|
|
; SOFT-NEXT: jal __gnu_f2h_ieee
|
|
; SOFT-NEXT: move $4, $2
|
|
; SOFT-NEXT: lw $16, 16($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 24
|
|
%ldexp = call half @llvm.ldexp.f16.i32(half %arg0, i32 %arg1)
|
|
ret half %ldexp
|
|
}
|
|
|
|
define x86_fp80 @ldexp_f80(x86_fp80 %arg0, i32 %arg1) {
|
|
; SOFT-LABEL: ldexp_f80:
|
|
; SOFT: # %bb.0:
|
|
; SOFT-NEXT: addiu $sp, $sp, -24
|
|
; SOFT-NEXT: .cfi_def_cfa_offset 24
|
|
; SOFT-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
|
|
; SOFT-NEXT: .cfi_offset 31, -4
|
|
; SOFT-NEXT: jal ldexpl
|
|
; SOFT-NEXT: andi $4, $4, 65535
|
|
; SOFT-NEXT: move $4, $2
|
|
; SOFT-NEXT: addiu $2, $zero, 0
|
|
; SOFT-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
|
|
; SOFT-NEXT: jr $ra
|
|
; SOFT-NEXT: addiu $sp, $sp, 24
|
|
%ldexp = call x86_fp80 @llvm.ldexp.f80.i32(x86_fp80 %arg0, i32 %arg1)
|
|
ret x86_fp80 %ldexp
|
|
}
|
|
|
|
|
|
declare double @llvm.ldexp.f64.i32(double, i32) #0
|
|
declare float @llvm.ldexp.f32.i32(float, i32) #0
|
|
declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #0
|
|
declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>) #0
|
|
declare x86_fp80 @llvm.ldexp.f80.i32(x86_fp80, i32)
|
|
declare half @llvm.ldexp.f16.i32(half, i32) #0
|
|
|
|
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|