Skip to content

Commit 57acdcf

Browse files
author
Victor Do Nascimento
committed
vect: Fix dominator update [PR123152]
The `recompute_dominator' function used in the code fragment within this patch assumes correctness in the rest of the CFG. Consequently, it is wrong to rely upon it before the subsequent updates are made in the "Update dominators for multiple exits" loop in the function. Furthermore, if `loop_exit' == `scalar_exit', the "Update dominators for multiple exits" logic will already take care of updating the dominator for `scalar_exit->dest', such that the moved statement is unnecessary. gcc/ChangeLog: PR tree-optimization/123152 * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Correct order of dominator update. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-uncounted-prolog-peel_2.c: New. * gcc.dg/vect/vect-uncounted-prolog-peel_3.c: Likewise. * g++.dg/vect/vect-uncounted-prolog-peel_1.cc: Likewise.
1 parent 15f7c58 commit 57acdcf

File tree

4 files changed

+111
-5
lines changed

4 files changed

+111
-5
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* { dg-add-options vect_early_break } */
2+
/* { dg-do compile } */
3+
/* { dg-require-effective-target vect_early_break } */
4+
/* { dg-require-effective-target vect_int } */
5+
/* { dg-additional-options "-w" } */
6+
7+
namespace a {
8+
class b {
9+
public:
10+
b d(long);
11+
};
12+
class e : public b {};
13+
typedef short f;
14+
typedef struct g *h;
15+
typedef struct g {
16+
f c;
17+
e *fp;
18+
f j, *k, *l;
19+
} m;
20+
static h n(m *, unsigned, unsigned *);
21+
f o(m *, unsigned);
22+
void p(short *t) {
23+
m *ffile;
24+
int q;
25+
unsigned r;
26+
int i;
27+
q = t[i];
28+
n(ffile, q, &r);
29+
}
30+
h n(m *ffile, unsigned q, unsigned *) {
31+
h glyph;
32+
for (; glyph;)
33+
if (glyph->c)
34+
o(ffile, q);
35+
int i;
36+
s:
37+
for (i = 0; ffile->j; i++)
38+
if (ffile->k[i]) {
39+
if (q)
40+
ffile->fp->d(ffile->l[i]);
41+
break;
42+
}
43+
if (q < 6) {
44+
q += 61440;
45+
goto s;
46+
}
47+
}
48+
} // namespace a
49+
50+
/* { dg-final { scan-tree-dump {note:\s*Alignment of access forced using peeling.} "vect" } } */
51+
/* { dg-final { scan-tree-dump {vectorized 1 loops in function} "vect" } } */
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* { dg-add-options vect_early_break } */
2+
/* { dg-do compile } */
3+
/* { dg-require-effective-target vect_early_break } */
4+
/* { dg-require-effective-target vect_int } */
5+
6+
char b;
7+
int c(char *d) {
8+
int *a = 0;
9+
while (*d) {
10+
while (*a)
11+
if (*a++ == 1)
12+
return 1;
13+
d++;
14+
}
15+
}
16+
void e() {
17+
c(&b);
18+
char *f = &b;
19+
while (f[0])
20+
++b;
21+
}
22+
23+
/* { dg-final { scan-tree-dump {note:\s*Alignment of access forced using peeling.} "vect" } } */
24+
/* { dg-final { scan-tree-dump {if \(ivtmp_[0-9_]+ >= prolog_loop_niters.[0-9_]+\)\n\s*goto} "vect" } } */
25+
/* { dg-final { scan-tree-dump {vectorized 1 loops in function} "vect" } } */
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* { dg-add-options vect_early_break } */
2+
/* { dg-do compile } */
3+
/* { dg-require-effective-target vect_early_break } */
4+
/* { dg-require-effective-target vect_int } */
5+
6+
struct {
7+
int segments[];
8+
} seek_to_sample_coarse_f;
9+
10+
int seek_to_sample_coarse_i, seek_to_sample_coarse_f_1;
11+
12+
void seek_to_sample_coarse() {
13+
int end_pos = seek_to_sample_coarse_f_1;
14+
for (;;) {
15+
seek_to_sample_coarse_i = end_pos;
16+
for (; end_pos > 0; --end_pos)
17+
if (seek_to_sample_coarse_f.segments[end_pos - 1])
18+
break;
19+
if (end_pos)
20+
break;
21+
}
22+
}
23+
24+
/* { dg-final { scan-tree-dump {note:\s*Alignment of access forced using peeling.} "vect" } } */
25+
/* { dg-final { scan-tree-dump {if \(ivtmp_[0-9_]+ >= prolog_loop_niters.[0-9_]+\)\n\s*goto} "vect" } } */
26+
/* { dg-final { scan-tree-dump {vectorized 1 loops in function} "vect" } } */

gcc/tree-vect-loop-manip.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,11 +1989,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
19891989
flush_pending_stmts (new_exit);
19901990
set_immediate_dominator (CDI_DOMINATORS, preheader, new_exit->src);
19911991

1992-
if (create_main_e)
1993-
set_immediate_dominator (CDI_DOMINATORS, scalar_exit->dest,
1994-
recompute_dominator (CDI_DOMINATORS,
1995-
scalar_exit->dest));
1996-
19971992
/* And remove the non-necessary forwarder again. Keep the other
19981993
one so we have a proper pre-header for the loop at the exit edge. */
19991994
redirect_edge_pred (single_succ_edge (new_preheader),
@@ -2024,6 +2019,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
20242019
}
20252020
}
20262021
}
2022+
2023+
/* When loop_exit != scalar_exit due to if-conversion loop versioning,
2024+
the `scalar_exit' now has two incoming edges, one from the if-converted
2025+
and one from the peeled prolog loop. It is therefore dominated by a
2026+
common block between these. Update its dominator accordingly. */
2027+
if (create_main_e && loop_exit != scalar_exit)
2028+
set_immediate_dominator (CDI_DOMINATORS, scalar_exit->dest,
2029+
recompute_dominator (CDI_DOMINATORS,
2030+
scalar_exit->dest));
20272031
}
20282032

20292033
free (new_bbs);

0 commit comments

Comments
 (0)