diff mbox series

[committed] Fix v850e divmodhi4 and udivmodhi4

Message ID aed50530-9468-dfba-aa6b-8ce66639557a@redhat.com
State New
Headers show
Series [committed] Fix v850e divmodhi4 and udivmodhi4 | expand

Commit Message

Jeff Law June 25, 2018, 4:01 p.m. UTC
Discovered when analyzing testresults for the v850.

There's two bugs lurking in those patterns.  The most serious is the
divmodhi4 pattern.  It takes a 32bit dividend and divides it by the low
16 bits of the divisor.

However, being a HImode pattern, we've assumed the upper 16 bits of the
divisor don't affect the result.  Consider -9216 as the divisor.  We may
have loaded that via a movhi from memory with zero extension resulting
in 0x0000dc00 as the divisor which looks like 56320 since the dividend
is actually 32 bits.  Opps.

The fix is to sign extend the dividend for divmodhi4 much like we were
already zero extending it for udivmodhi4.  Of course we need to fix the
length while we're at it...

Which brings us to the second bug.  The udivmodhi4 pattern claimed to
have a length of "4", but that's not right.  The div instruction alone
has a length of "4", but we're also emitting a zero-extension, so the
total length is actually 6.

Rather than use

extend ; div

In the output template, I'm now using

extend\n\tdiv

The latter gives better results when fed into the assembler with -al to
verify lengths.

This fixes a handful of execution failures on the v850e3v5 tests.
Installing on the trunk.

Jeff
diff mbox series

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 754b5f10063..ceec833bb70 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2018-06-25  Jeff Law  <law@redhat.com>
+
+	* config/v850/v850.md (divmodhi4): Make sure to sign extend the
+	dividend to 32 bits.  Adjust length.
+	(udivmodhi4): Cleanup output template.  Fix length.
+
 2018-06-25  Carl Love  <cel@us.ibm.com>
 
 	* config/rs6000/vsx.md: Change word selector to prefered location.
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 2656e90c90b..e01a3102c31 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -738,13 +738,13 @@ 
 		(match_dup 2)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_V850E_UP"
-  "divh %2,%0,%3"
-  [(set_attr "length" "4")
+  "sxh %0\n\tdivh %2,%0,%3"
+  [(set_attr "length" "6")
    (set_attr "cc" "clobber")
    (set_attr "type" "div")])
 
-;; Half-words are sign-extended by default, so we must zero extend to a word
-;; here before doing the divide.
+;; The half word needs to be zero/sign extended to 32 bits before doing
+;; the division/modulo operation.
 
 (define_insn "udivmodhi4"
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -755,8 +755,8 @@ 
 		 (match_dup 2)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_V850E_UP"
-  "zxh %0 ; divhu %2,%0,%3"
-  [(set_attr "length" "4")
+  "zxh %0\n\tdivhu %2,%0,%3"
+  [(set_attr "length" "6")
    (set_attr "cc" "clobber")
    (set_attr "type" "div")])