--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-std=c++17 -O2" } */
+
+template <int Size> struct Vector {
+ int m_data[Size];
+ Vector(int, int, int) {}
+};
+enum class E { POINTS, LINES, TRIANGLES };
+
+__attribute__((noipa))
+void getName(E type) {
+ static E check = E::POINTS;
+ if (type == check)
+ check = (E)((int)check + 1);
+ else
+ __builtin_abort ();
+}
+
+int main() {
+ int arr[]{0, 1, 2};
+ for (auto dim : arr) {
+ Vector<3> localInvs(1, 1, 1);
+ localInvs.m_data[dim] = 8;
+ }
+ E types[] = {E::POINTS, E::LINES, E::TRIANGLES};
+ for (auto primType : types)
+ getName(primType);
+ return 0;
+}
#include "builtins.h"
#include "tree-sra.h"
#include "opts.h"
+#include "tree-ssa-alias-compare.h"
/* Enumeration of all aggregate reductions we can do. */
enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
access->type = TREE_TYPE (expr);
access->write = write;
access->grp_unscalarizable_region = unscalarizable_region;
+ access->grp_same_access_path = true;
access->stmt = stmt;
access->reverse = reverse;
racc = build_access_from_expr_1 (rhs, stmt, false);
lacc = build_access_from_expr_1 (lhs, stmt, true);
+ bool tbaa_hazard
+ = !types_equal_for_same_type_for_tbaa_p (TREE_TYPE (lhs), TREE_TYPE (rhs));
+
if (lacc)
{
lacc->grp_assignment_write = 1;
bitmap_set_bit (cannot_scalarize_away_bitmap,
DECL_UID (lacc->base));
}
+ if (tbaa_hazard)
+ lacc->grp_same_access_path = false;
}
if (racc)
}
if (storage_order_barrier_p (lhs))
racc->grp_unscalarizable_region = 1;
+ if (tbaa_hazard)
+ racc->grp_same_access_path = false;
}
if (lacc && racc
bool grp_partial_lhs = access->grp_partial_lhs;
bool first_scalar = is_gimple_reg_type (access->type);
bool unscalarizable_region = access->grp_unscalarizable_region;
- bool grp_same_access_path = true;
+ bool grp_same_access_path = access->grp_same_access_path;
bool bf_non_full_precision
= (INTEGRAL_TYPE_P (access->type)
&& TYPE_PRECISION (access->type) != access->size
return NULL;
}
- grp_same_access_path = path_comparable_for_same_access (access->expr);
+ if (grp_same_access_path)
+ grp_same_access_path = path_comparable_for_same_access (access->expr);
j = i + 1;
while (j < access_count)
}
if (grp_same_access_path
- && !same_access_path_p (access->expr, ac2->expr))
+ && (!ac2->grp_same_access_path
+ || !same_access_path_p (access->expr, ac2->expr)))
grp_same_access_path = false;
ac2->group_representative = access;
#include "tree-ssa-alias-compare.h"
#include "builtins.h"
#include "internal-fn.h"
+#include "ipa-utils.h"
/* Broad overview of how alias analysis on gimple works:
}
/* Return ture if TYPE1 and TYPE2 will always give the same answer
- when compared wit hother types using same_type_for_tbaa_p. */
+ when compared with other types using same_type_for_tbaa. */
static bool
types_equal_for_same_type_for_tbaa_p (tree type1, tree type2,
return TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2);
}
+/* Return ture if TYPE1 and TYPE2 will always give the same answer
+ when compared with other types using same_type_for_tbaa. */
+
+bool
+types_equal_for_same_type_for_tbaa_p (tree type1, tree type2)
+{
+ return types_equal_for_same_type_for_tbaa_p (type1, type2,
+ lto_streaming_expected_p ());
+}
+
/* Compare REF1 and REF2 and return flags specifying their differences.
If LTO_STREAMING_SAFE is true do not use alias sets and canonical
types that are going to be recomputed.