Bug 46679 - fold_binary changes types in divisionm breaking configure -enable-checking
Summary: fold_binary changes types in divisionm breaking configure -enable-checking
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-27 00:46 UTC by Jay
Modified: 2010-12-02 09:08 UTC (History)
0 users

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jay 2010-11-27 00:46:56 UTC
fold_binary seemingly changes the types of division inputs (but not the output),
leading to configure -enable-checking to fail.


My code is something like this (using a different frontend
and slightly patched 4.5.1 but I don't think relevantly):


long a;

long F(void)
{
 return a / a;
}

configure -enable-checking=fold,...:

gcc-4.5
fold-const.c

fold_binary_loc(code = FLOOR_DIV_EXPR,
                op0, op1, type all int_64


arg0, arg1 become word_64
(not op0, op1, but arg0, arg1)


and then we end up here:

      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
      && multiple_of_p (type, arg0, arg1))
    return fold_build2_loc (loc, EXACT_DIV_EXPR, type, arg0, arg1);


and then:


error: type mismatch in binary expression
int_64
word_64
word_64


D.1003 = D.1001 /[ex] D.1002;


multiple_of_p is true because the operands are the same.
 (This would optimize to 1, unless the operands might be 0.)
 

I'll see if I can reproduce with unpatched C 4.5.1 and trunk.


 - Jay
Comment 1 Jay 2010-12-02 09:08:49 UTC
You can "prove", almost, the existance of the bug by
making this change to slightly increase it:

jbook2:gcc jay$ svn diff  fold-const.c 
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 167194)
+++ fold-const.c	(working copy)
@@ -11648,7 +11648,7 @@
 	 Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now.
 	 At one time others generated faster code, it's not clear if they do
 	 after the last round to changes to the DIV code in expmed.c.  */
-      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
+      if ((code == CEIL_DIV_EXPR || code == TRUNC_DIV_EXPR || code == FLOOR_DIV_EXPR)
 	  && multiple_of_p (type, arg0, arg1))
 	return fold_build2_loc (loc, EXACT_DIV_EXPR, type, arg0, arg1);


it: I don't think C ever produces ceil_div/floor_div, so
it's hard to demonstrate.

With this, bootstrap fails:


/src/gcc-trunk/configure -prefix=/usr/local/gcc-trunk -enable-checking=assert,df,fold,misc,rtl,rtlflag,runtime,tree,types && make -j4

/src/gcc-trunk/gcc/tree-ssa-loop-prefetch.c:1503:1: error: type mismatch in binary expression
unsigned int
int
unsigned int
D.55547 = D.55546 /[ex] 16;

other than just removing this chunk of code completely,
I might suggest checking that arg0 == op0 && arg1 == op1.
Though that is probably a bit more conservative than necessary.