On 11/11/16 15:42, James Greenhalgh wrote:
Hi,
This patch adds the half-to-double conversions, both as library functions,
or when supported in hardware, using the appropriate instructions.
That means adding support for the __gnu_d2h_{ieee/alternative} library calls
added in patch 2/4, and providing a more aggressive truncdfhf2 where we can.
This also lets us remove the implementation of TARGET_CONVERT_TO_TYPE.
Bootstrapped on an ARMv8-A machine,and crosstested with no issues.
OK?
Thanks,
James
---
gcc/
2016-11-09 James Greenhalgh <james.greenha...@arm.com>
* config/arm/arm.c (arm_convert_to_type): Delete.
(TARGET_CONVERT_TO_TYPE): Delete.
(arm_init_libfuncs): Enable trunc_optab from DFmode to HFmode.
(arm_libcall_uses_aapcs_base): Add trunc_optab from DF- to HFmode.
* config/arm/arm.h (TARGET_FP16_TO_DOUBLE): New.
* config/arm/arm.md (truncdfhf2): Only convert through SFmode if we
are in fast math mode, and have no single step hardware instruction.
(extendhfdf2): Only expand through SFmode if we don't have a
single-step hardware instruction.
* config/arm/vfp.md (*truncdfhf2): New.
(extendhfdf2): Likewise.
gcc/testsuite/
2016-11-09 James Greenhalgh <james.greenha...@arm.com>
* gcc.target/arm/fp16-rounding-alt-1.c (ROUNDED): Change expected
result.
* gcc.target/arm/fp16-rounding-ieee-1.c (ROUNDED): Change expected
result.
<...>
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8393f65..4074773 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -5177,20 +5177,35 @@
""
)
-;; DFmode to HFmode conversions have to go through SFmode.
+;; DFmode to HFmode conversions on targets without a single-step hardware
+;; instruction for it would have to go through SFmode. This is dangerous
+;; as it introduces double rounding.
+;;
+;; Disable this pattern unless we are in an unsafe math mode, or we have
+;; a single-step instruction.
+
(define_expand "truncdfhf2"
- [(set (match_operand:HF 0 "general_operand" "")
+ [(set (match_operand:HF 0 "s_register_operand" "")
(float_truncate:HF
- (match_operand:DF 1 "general_operand" "")))]
- "TARGET_EITHER"
- "
- {
- rtx op1;
- op1 = convert_to_mode (SFmode, operands[1], 0);
- op1 = convert_to_mode (HFmode, op1, 0);
- emit_move_insn (operands[0], op1);
- DONE;
- }"
+ (match_operand:DF 1 "s_register_operand" "")))]
+ "(TARGET_EITHER && flag_unsafe_math_optimizations)
+ || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
+{
+ /* We don't have a direct instruction for this, so we must be in
+ an unsafe math mode, and going via SFmode. */
+
+ if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
+ {
+ rtx op1;
+ gcc_assert (flag_unsafe_math_optimizations);
I'd remove this assert. From the condition of the expander it is obvious
that if !(TARGET_32BIT && TARGET_FP16_TO_DOUBLE) then
flag_unsafe_math_optimizations is true.
Ok with this change.
Thanks,
Kyrill