https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105030
--- Comment #11 from HaoChen Gui <guihaoc at gcc dot gnu.org> --- I tested C source code with Ofast. The Ofast enables data store race. It should do store motion but it fails. The problem is on cselim pass. It does conditional store replacement. The 'atemp' is converted to its alias set - 'MEM <double> [(void *)&atemp]' in the if-else blocks and remains untouch out of the if-else. atemp.0_5 = atemp; if (_4 < atemp.0_5) goto <bb 5>; [50.00%] else goto <bb 4>; [50.00%] <bb 4> [local count: 477815113]: cstore_18 = MEM <double> [(void *)&atemp]; <bb 5> [local count: 955630225]: # cstore_17 = PHI <cstore_18(4), _4(3)> MEM <double> [(void *)&atemp] = cstore_17; Then in lim2 pass, it thinks 'atemp' and 'MEM <double> [(void *)&atemp]' are independent. So the store can't be moved out. Memory reference 1: *_3 Memory reference 2: atemp Memory reference 3: MEM <double> [(void *)&atemp] Querying dependency of refs 3 and 1: independent. Querying dependency of refs 3 and 2: dependent. Querying SM WAR dependencies of ref 3 in loop 1: dependent I wonder if 'atemp' is equivalent to 'MEM <double> [(void *)&atemp]'. Why we shall use alias-set zero in cselim pass. /* Make both store and load use alias-set zero as we have to deal with the case of the store being a conditional change of the dynamic type. */ while (handled_component_p (*basep)) basep = &TREE_OPERAND (*basep, 0); if (TREE_CODE (*basep) == MEM_REF || TREE_CODE (*basep) == TARGET_MEM_REF) TREE_OPERAND (*basep, 1) = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1)); else *basep = build2 (MEM_REF, TREE_TYPE (*basep), build_fold_addr_expr (*basep), build_zero_cst (ptr_type_node));