On Tue, 2 Dec 2014, Richard Biener wrote:

> > I'm not sure if these forms of division actually occur in places where 
> > this could cause a problem, but it does look like Ada may enable you to 
> > generate ROUND_DIV_EXPR.
> 
> Hmm.  I thought I was following what extract_muldiv_1 does (but of course
> that function is quite hard to follow).

I don't claim existing optimizations are correct for all these forms of 
division.

In fact even wide-int doesn't handle ROUND_DIV_EXPR correctly (round to 
nearest, ties away from 0) - at a glance, without testing, ROUND_MOD_EXPR 
has the same bug (wi::ges_p (wi::abs (remainder), wi::lrshift (wi::abs 
(y), 1)) is not the right condition for rounding away).  The following Ada 
testcase test_round_div.adb will generate a ROUND_DIV_EXPR which is 
executed correctly at -O0, but fails at -O3.  (The separate division 
function seems necessary to stop the front end from doing its own constant 
folding, though there may for all I know be more idiomatic Ada ways of 
doing that.)

procedure Test_Round_Div is
   type Fixed is delta 1.0 range -2147483648.0 .. 2147483647.0;
   A : Fixed := 1.0;
   B : Fixed := 3.0;
   C : Integer;
   function Divide (X, Y : Fixed) return Integer is
   begin
      return Integer (X / Y);
   end;
begin
   C := Divide (A, B);
   if C /= 0 then
      raise Program_Error;
   end if;
end Test_Round_Div;

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to