> Jan Hubicka wrote: > >Yep, they should not roduce incorrect code. Isn't the problem > >that you expect the whole expression to have value and predit_expr > >"reutrns" nothing? > >Can you check what lands into gimple? > > That could well be the case – I replace "0" by "{ built_predict; 0 > }" and I wouldn't be surprised if the built_predict causes problem
Yep, though this is also the case whrere you really want to predict a value rather than code path, so the extended bultin_expect is probably only resonable approach here. I am not really generic person, but perhaps it is a difference in between { built_predict; 0 } that is stmt with no value and built_predict,0 that is an expression with value? I will look into the builtin_expect extension. Then we can probably keem gfc_likely/unlikely with extra argument specifying the predictor for cases like this and use predict_expr in cases where you really produce runtime conditional like if (...) { bulitin_predict; abort ();} Honza > as it returns 'nothing'. At least the basic block belonging to > "else" (<D.1934>) is empty: > > Original dump (4.8 and 4.9 with predict patch): > sub1 (&v[S.0 + -1], (logical(kind=4)) __builtin_expect > ((integer(kind=8)) (D.1897 == 0B), 0) ? 0B : &(*D.1897)[(S.0 + > D.1901) * D.1903 + D.1898]); > and > sub1 (&v[S.0 + -1], D.1917 != 0B ? &(*D.1917)[(S.0 + > D.1921) * D.1923 + D.1918] : (void) 0); > > Gimple of 4.8: > if (D.1916 != 0) goto <D.1917>; else goto <D.1918>; > <D.1917>: > iftmp.2 = 0B; > goto <D.1919>; > <D.1918>: > ... > iftmp.2 = &*D.1897[D.1922]; > <D.1919>: > .. > sub1 (D.1924, iftmp.2); > > gimple of 4.9 with patch: > if (D.1917 != 0B) goto <D.1933>; else goto <D.1934>; > <D.1933>: > D.1935 = S.0 + D.1921; > D.1936 = D.1935 * D.1923; > D.1937 = D.1936 + D.1918; > iftmp.2 = &*D.1917[D.1937]; > goto <D.1938>; > <D.1934>: > <D.1938>: > D.1939 = S.0 + -1; > D.1940 = &v[D.1939]; > sub1 (D.1940, iftmp.2); > > Tobias > > PS: That's for the code: > > implicit none > type t2 > integer, allocatable :: a > integer, pointer :: p2(:) => null() > end type t2 > type(t2), save :: x > integer, save :: s, v(2) > call sub1 (v, x%p2) > contains > elemental subroutine sub1 (x, y) > integer, intent(inout) :: x > integer, intent(in), optional :: y > end subroutine sub1 > end