This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix v850e divmodhi4 and udivmodhi4
- From: Jeff Law <law at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 25 Jun 2018 10:01:50 -0600
- Subject: [committed] Fix v850e divmodhi4 and udivmodhi4
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 --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")])