Hi, this is a fallout of one of my gimplifier changes. For the attached testcase, the compiler generates invalid GIMPLE at -O1 or above:
p.adb: In function 'P.F': p.adb:24:1: error: invalid operand in unary operation D.2361_107 = (integer[1:1] *) &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}; if (!is_gimple_val (rhs1)) { error ("invalid operand in unary operation"); return true; } (gdb) p rhs_code $6 = NOP_EXPR (gdb) p debug_generic_expr(rhs1) &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4} i.e ADDR_EXPR of ARRAY_RANGE_REF with non-constant operand #1. The invalid statement is generated by the early SRA pass: integer a1[1:1]; VIEW_CONVERT_EXPR<integer[1:1]>(*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}) = a1; is rewritten into: Created a replacement for a1 offset: 0, size: 32: a1$1 D.2361_107 = (integer[1:1] *) &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}; MEM[(integer[1:D.2312] *)D.2361_107] = a1$1_92; It turns out that the problematic NOP_EXPR is a useless type conversion emitted by build_fold_addr_expr: if you add a call to force_gimple_operand at the hot spot, it ends up removing the NOP_EXPR and nothing else. So the proposed fix is just to add a call to STRIP_USELESS_TYPE_CONVERSION there. Tested on i586-suse-linux, OK for the mainline? 2011-03-23 Eric Botcazou <ebotca...@adacore.com> * tree-sra.c (build_ref_for_offset): Call STRIP_USELESS_TYPE_CONVERSION on the address built for a reference with variable offset. 2011-03-23 Eric Botcazou <ebotca...@adacore.com> * gnat.dg/array15.ad[sb]: New test. * gnat.dg/array15_pkg.ads: New helper. -- Eric Botcazou
-- { dg-do compile } -- { dg-options "-O -gnatws" } package body P is type Arr is array (Natural range <>) of Integer; Table : Arr (1 .. 4); N : Natural := 1; procedure Zero is begin N := 0; end; function F (I : Integer) return Integer is A1 : Arr := (1 => I); A2 : Arr := Table (1 .. N) & A1; begin return A2 (I); end; end P;
package P is function F (I : Integer) return Integer; end P;
package Q is type Arr is array (Natural range <>) of Integer; procedure Proc (A : Arr); end Q;
Index: tree-sra.c =================================================================== --- tree-sra.c (revision 171345) +++ tree-sra.c (working copy) @@ -1376,6 +1376,7 @@ build_ref_for_offset (location_t loc, tr add_referenced_var (tmp); tmp = make_ssa_name (tmp, NULL); addr = build_fold_addr_expr (unshare_expr (prev_base)); + STRIP_USELESS_TYPE_CONVERSION (addr); stmt = gimple_build_assign (tmp, addr); gimple_set_location (stmt, loc); SSA_NAME_DEF_STMT (tmp) = stmt;