@@ -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