78 lines
1.9 KiB
Diff
78 lines
1.9 KiB
Diff
2019-01-21 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR rtl-optimization/88904
|
|
* cfgcleanup.c (thread_jump): Verify cond2 doesn't mention
|
|
any nonequal registers before processing BB_END (b).
|
|
|
|
* gcc.c-torture/execute/pr88904.c: New test.
|
|
|
|
--- gcc/cfgcleanup.c.jj 2019-01-01 12:37:19.147942300 +0100
|
|
+++ gcc/cfgcleanup.c 2019-01-21 16:45:52.576636305 +0100
|
|
@@ -338,6 +338,13 @@ thread_jump (edge e, basic_block b)
|
|
insn != NEXT_INSN (BB_END (b)) && !failed;
|
|
insn = NEXT_INSN (insn))
|
|
{
|
|
+ /* cond2 must not mention any register that is not equal to the
|
|
+ former block. Check this before processing that instruction,
|
|
+ as BB_END (b) could contain also clobbers. */
|
|
+ if (insn == BB_END (b)
|
|
+ && mentions_nonequal_regs (cond2, nonequal))
|
|
+ goto failed_exit;
|
|
+
|
|
if (INSN_P (insn))
|
|
{
|
|
rtx pat = PATTERN (insn);
|
|
@@ -362,11 +369,6 @@ thread_jump (edge e, basic_block b)
|
|
goto failed_exit;
|
|
}
|
|
|
|
- /* cond2 must not mention any register that is not equal to the
|
|
- former block. */
|
|
- if (mentions_nonequal_regs (cond2, nonequal))
|
|
- goto failed_exit;
|
|
-
|
|
EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
|
|
goto failed_exit;
|
|
|
|
--- gcc/testsuite/gcc.c-torture/execute/pr88904.c.jj 2019-01-21 16:47:16.194265770 +0100
|
|
+++ gcc/testsuite/gcc.c-torture/execute/pr88904.c 2019-01-21 16:46:59.278543027 +0100
|
|
@@ -0,0 +1,38 @@
|
|
+/* PR rtl-optimization/88904 */
|
|
+
|
|
+volatile int v;
|
|
+
|
|
+__attribute__((noipa)) void
|
|
+bar (const char *x, const char *y, int z)
|
|
+{
|
|
+ if (!v)
|
|
+ __builtin_abort ();
|
|
+ asm volatile ("" : "+g" (x));
|
|
+ asm volatile ("" : "+g" (y));
|
|
+ asm volatile ("" : "+g" (z));
|
|
+}
|
|
+
|
|
+#define my_assert(e) ((e) ? (void) 0 : bar (#e, __FILE__, __LINE__))
|
|
+
|
|
+typedef struct {
|
|
+ unsigned M1;
|
|
+ unsigned M2 : 1;
|
|
+ int : 0;
|
|
+ unsigned M3 : 1;
|
|
+} S;
|
|
+
|
|
+S
|
|
+foo ()
|
|
+{
|
|
+ S result = {0, 0, 1};
|
|
+ return result;
|
|
+}
|
|
+
|
|
+int
|
|
+main ()
|
|
+{
|
|
+ S ret = foo ();
|
|
+ my_assert (ret.M2 == 0);
|
|
+ my_assert (ret.M3 == 1);
|
|
+ return 0;
|
|
+}
|