Bug 79752 - incorrect code generation for __divkf3 with -O2 -mcpu=power9
Summary: incorrect code generation for __divkf3 with -O2 -mcpu=power9
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: acsawdey
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2017-02-28 17:00 UTC by acsawdey
Modified: 2017-03-14 14:43 UTC (History)
5 users (show)

See Also:
Host:
Target: powerpc64*-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
reduced test case (4.58 KB, text/x-csrc)
2017-02-28 17:00 UTC, acsawdey
Details

Note You need to log in before you can comment on or make changes to this bug.
Description acsawdey 2017-02-28 17:00:56 UTC
Created attachment 40845 [details]
reduced test case

Trunk 245614 is generating incorrect code for the software version of divkf3 with -mcpu=power9. With -mcpu=power8, correct code is generated.

I've applied multidelta to this test case but it wasn't able to remove much.

gcc/xgcc -Bgcc/ -O2 -mcpu=power9 -o divkf3bug divkf3bug.c
./divkf3bug
a=2.000000 b=3.000000 r=1.999999

gcc/xgcc -Bgcc/ -O2 -mcpu=power8 -o divkf3bug divkf3bug.c
./divkf3bug
a=2.000000 b=3.000000 r=0.666667
Comment 1 acsawdey 2017-02-28 21:13:42 UTC
Meissner spotted the cause. Verified that this fixes it:

Index: ../trunk/gcc/config/rs6000/rs6000.md
===================================================================
--- ../trunk/gcc/config/rs6000/rs6000.md        (revision 245787)
+++ ../trunk/gcc/config/rs6000/rs6000.md        (working copy)
@@ -3161,7 +3161,7 @@
    && ! reg_mentioned_p (operands[3], operands[1])
    && ! reg_mentioned_p (operands[3], operands[2])"
   [(set (match_dup 0)
-       (div:GPR (match_dup 1)
+       (udiv:GPR (match_dup 1)
                 (match_dup 2)))
    (set (match_dup 3)
        (mult:GPR (match_dup 0)

Now to bootstrap/regtest this and post.
Comment 2 Michael Meissner 2017-02-28 23:29:10 UTC
On Tue, Feb 28, 2017 at 09:13:42PM +0000, acsawdey at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79752
> 
> --- Comment #1 from acsawdey at gcc dot gnu.org ---
> Meissner spotted the cause. Verified that this fixes it:
> 
> Index: ../trunk/gcc/config/rs6000/rs6000.md
> ===================================================================
> --- ../trunk/gcc/config/rs6000/rs6000.md        (revision 245787)
> +++ ../trunk/gcc/config/rs6000/rs6000.md        (working copy)
> @@ -3161,7 +3161,7 @@
>     && ! reg_mentioned_p (operands[3], operands[1])
>     && ! reg_mentioned_p (operands[3], operands[2])"
>    [(set (match_dup 0)
> -       (div:GPR (match_dup 1)
> +       (udiv:GPR (match_dup 1)
>                  (match_dup 2)))
>     (set (match_dup 3)
>         (mult:GPR (match_dup 0)
> 
> Now to bootstrap/regtest this and post.

One minor formatting nit.  When you change div -> udiv, you will need to
indent the (match_dup 20 on the next line by one space.
Comment 3 acsawdey 2017-03-01 19:58:36 UTC
Author: acsawdey
Date: Wed Mar  1 19:58:05 2017
New Revision: 245817

URL: https://gcc.gnu.org/viewcvs?rev=245817&root=gcc&view=rev
Log:
2017-03-01  Aaron Sawdey  <acsawdey@linux.vnet.ibm.com>

        PR target/79752
        * config/rs6000/rs6000.md (peephole2 for udiv/umod): Should emit
        udiv rather than div since input pattern is unsigned.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/rs6000.md
Comment 4 acsawdey 2017-03-03 23:35:11 UTC
Fixed in 245817.
Comment 5 acsawdey 2017-03-14 14:43:36 UTC
Author: acsawdey
Date: Tue Mar 14 14:43:03 2017
New Revision: 246127

URL: https://gcc.gnu.org/viewcvs?rev=246127&root=gcc&view=rev
Log:
This showed up in power9 code for __divkf3 software float support and
caused a divd to be emitted where we needed a divdu.

Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 246123)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -3063,8 +3063,8 @@
    && ! reg_mentioned_p (operands[3], operands[1])
    && ! reg_mentioned_p (operands[3], operands[2])"
   [(set (match_dup 0)
-       (div:GPR (match_dup 1)
-                (match_dup 2)))
+       (udiv:GPR (match_dup 1)
+                 (match_dup 2)))
    (set (match_dup 3)
        (mult:GPR (match_dup 0)
                  (match_dup 2)))

2017-03-14  Aaron Sawdey  <acsawdey@linux.vnet.ibm.com>

	Backport from mainline
	2017-02-28  Aaron Sawdey  <acsawdey@linux.vnet.ibm.com>

	PR target/79752
        * config/rs6000/rs6000.md (peephole2 for udiv/umod): Should emit
        udiv rather than div since input pattern is unsigned.



Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/config/rs6000/rs6000.md