https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98282
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu.org --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, the ICE is because compute_avail gets called twice on VIEW_CONVERT_EXPR from NULL to decltype(nullptr): stmt: _7 = VIEW_CONVERT_EXPR<<<< Unknown tree: nullptr_type >>>>(0B); rhs1: <view_convert_expr 0x7fffe9ddd0e0 type <nullptr_type 0x7fffea1a3c78 decltype(nullptr) unsigned type_6 DI size <integer_cst 0x7fffea041eb8 constant 64> unit-size <integer_cst 0x7fffea041ed0 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set 14 canonical-type 0x7fffea1a3c78 pointer_to_this <pointer_type 0x7fffea21db28> reference_to_this <reference_type 0x7fffea1eb738>> constant arg:0 <integer_cst 0x7fffea1b0b28 type <pointer_type 0x7fffea1c3a80> constant 0> pr98282.ii:19:13 start: pr98282.ii:19:13 finish: pr98282.ii:19:16> TREE_TYPE (TREE_OPERAND (rhs1, 0)): <pointer_type 0x7fffea1c3a80 type <integer_type 0x7fffea1c35e8 l sizes-gimplified type_6 SI size <integer_cst 0x7fffea062108 constant 32> unit-size <integer_cst 0x7fffea062120 constant 4> align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffea05f5e8 precision:32 min <integer_cst 0x7fffea0620c0 -2147483648> max <integer_cst 0x7fffea0620d8 2147483647> pointer_to_this <pointer_type 0x7fffea1c3a80>> public unsigned DI size <integer_cst 0x7fffea041eb8 type <integer_type 0x7fffea05f0a8 bitsizetype> constant 64> unit-size <integer_cst 0x7fffea041ed0 type <integer_type 0x7fffea05f000 sizetype> constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffea0679d8> TYPE_CANONICAL (TREE_TYPE (TREE_OPERAND (rhs1, 0))): <pointer_type 0x7fffea0679d8 type <integer_type 0x7fffea05f5e8 int sizes-gimplified public type_6 SI size <integer_cst 0x7fffea062108 constant 32> unit-size <integer_cst 0x7fffea062120 constant 4> align:32 warn_if_not_align:0 symtab:0 alias-set 10 canonical-type 0x7fffea05f5e8 precision:32 min <integer_cst 0x7fffea0620c0 -2147483648> max <integer_cst 0x7fffea0620d8 2147483647> pointer_to_this <pointer_type 0x7fffea0679d8>> unsigned DI size <integer_cst 0x7fffea041eb8 type <integer_type 0x7fffea05f0a8 bitsizetype> constant 64> unit-size <integer_cst 0x7fffea041ed0 type <integer_type 0x7fffea05f000 sizetype> constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set 4 canonical-type 0x7fffea0679d8> The alias-set 4 above means get_alias_set on the VCE returns 4. Second case: stmt: _8 = VIEW_CONVERT_EXPR<<<< Unknown tree: nullptr_type >>>>(0B); rhs1: <view_convert_expr 0x7fffe9ddd120 type <nullptr_type 0x7fffea1a3c78 decltype(nullptr) unsigned type_6 DI size <integer_cst 0x7fffea041eb8 constant 64> unit-size <integer_cst 0x7fffea041ed0 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set 14 canonical-type 0x7fffea1a3c78 pointer_to_this <pointer_type 0x7fffea21db28> reference_to_this <reference_type 0x7fffea1eb738>> constant arg:0 <integer_cst 0x7fffea1b09f0 type <pointer_type 0x7fffea1bf0a8 i> constant 0> pr98282.ii:15:15 start: pr98282.ii:15:15 finish: pr98282.ii:15:15> TREE_TYPE (TREE_OPERAND (rhs1, 0)): <pointer_type 0x7fffea1bf0a8 i type <record_type 0x7fffea1b5dc8 h sizes-gimplified addressable needs-constructing cxx-odr-p type_5 type_6 BLK size <integer_cst 0x7fffea1d35b8 constant 96> unit-size <integer_cst 0x7fffea1d35d0 constant 12> align:32 warn_if_not_align:0 symtab:0 alias-set 17 canonical-type 0x7fffea1b5dc8 fields <function_decl 0x7fffea213800 operator= type <method_type 0x7fffea212d20> addressable used nothrow public static weak autoinline decl_3 decl_5 QI defer-output pr98282.ii:60:8 align:16 warn_if_not_align:0 context <record_type 0x7fffea1b5dc8 h> initial <block 0x7fffea1e3600> result <result_decl 0x7fffea1fa438 D.3000> full-name "h& h::operator=(h&&)" chain <function_decl 0x7fffea213700 operator=>> context <translation_unit_decl 0x7fffea04e168 pr98282.ii> full-name "struct h" needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this <pointer_type 0x7fffea1bf000> reference_to_this <reference_type 0x7fffea2120a8> chain <type_decl 0x7fffea1be000 h>> public unsigned DI size <integer_cst 0x7fffea041eb8 type <integer_type 0x7fffea05f0a8 bitsizetype> constant 64> unit-size <integer_cst 0x7fffea041ed0 type <integer_type 0x7fffea05f000 sizetype> constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffea1bf000> TYPE_CANONICAL (TREE_TYPE (TREE_OPERAND (rhs1, 0))): <pointer_type 0x7fffea1bf000 type <record_type 0x7fffea1b5dc8 h sizes-gimplified addressable needs-constructing cxx-odr-p type_5 type_6 BLK size <integer_cst 0x7fffea1d35b8 constant 96> unit-size <integer_cst 0x7fffea1d35d0 constant 12> align:32 warn_if_not_align:0 symtab:0 alias-set 17 canonical-type 0x7fffea1b5dc8 fields <function_decl 0x7fffea213800 operator= type <method_type 0x7fffea212d20> addressable used nothrow public static weak autoinline decl_3 decl_5 QI defer-output pr98282.ii:60:8 align:16 warn_if_not_align:0 context <record_type 0x7fffea1b5dc8 h> initial <block 0x7fffea1e3600> result <result_decl 0x7fffea1fa438 D.3000> full-name "h& h::operator=(h&&)" chain <function_decl 0x7fffea213700 operator=>> context <translation_unit_decl 0x7fffea04e168 pr98282.ii> full-name "struct h" needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this <pointer_type 0x7fffea1bf000> reference_to_this <reference_type 0x7fffea2120a8> chain <type_decl 0x7fffea1be000 h>> public unsigned type_6 DI size <integer_cst 0x7fffea041eb8 type <integer_type 0x7fffea05f0a8 bitsizetype> constant 64> unit-size <integer_cst 0x7fffea041ed0 type <integer_type 0x7fffea05f000 sizetype> constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set 1 canonical-type 0x7fffea1bf000> And the alias-set 1 means get_alias_set on the second VCE returns 1. I think at least for the VCE of constant case (but VCE of SSA_NAME etc. would as well) we shouldn't consider alias set at all. So, one possible fix is: --- gcc/tree-ssa-pre.c.jj 2020-11-30 10:48:31.000000000 +0100 +++ gcc/tree-ssa-pre.c 2020-12-15 10:51:51.061206572 +0100 @@ -4176,13 +4176,17 @@ compute_avail (void) && ref2->opcode != MEM_REF && ref2 != &operands[0]) --ref2; - if ((ref1->opcode == TARGET_MEM_REF - || ref1->opcode == MEM_REF) - && (TYPE_ALIGN (ref1->type) - > TYPE_ALIGN (ref2->type))) - ref1->type - = build_aligned_type (ref1->type, - TYPE_ALIGN (ref2->type)); + if (ref1->opcode == TARGET_MEM_REF + || ref1->opcode == MEM_REF) + { + if (TYPE_ALIGN (ref1->type) + > TYPE_ALIGN (ref2->type)) + ref1->type + = build_aligned_type (ref1->type, + TYPE_ALIGN (ref2->type)); + } + else + set = ref->set; /* TBAA behavior is an obvious part so make sure that the hashtable one covers this as well by adjusting the ref alias set and its base. */ i.e. ignore the alias set if there is no MEM_REF or TARGET_MEM_REF, after all, the code below it relies on the alias sets to be equal except for MEM_REF or TARGET_MEM_REF. Another possibility would be for ao_ref_alias_set and ao_ref_base_alias_set to return 0 if they aren't really memory reads, such as VCE of constant or VCE of a SSA_NAME. And yet another would be not to call ao_ref_alias_set at all in the compute_avail code for such references, but do something different.