Bug 84742 - internal compiler error: in process_alt_operands, at lra-constraints.c:2112
Summary: internal compiler error: in process_alt_operands, at lra-constraints.c:2112
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 8.0.1
: P3 normal
Target Milestone: 8.0
Assignee: Jakub Jelinek
URL:
Keywords: ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2018-03-06 18:46 UTC by Vegard Nossum
Modified: 2018-03-08 20:56 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-03-08 00:00:00


Attachments
valgrind output (2.11 KB, text/plain)
2018-03-06 18:46 UTC, Vegard Nossum
Details
ASAN output (1.53 KB, text/plain)
2018-03-08 11:36 UTC, Vegard Nossum
Details
gcc8-pr84742.patch (565 bytes, patch)
2018-03-08 13:30 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vegard Nossum 2018-03-06 18:46:33 UTC
Created attachment 43580 [details]
valgrind output

Input:

void a() {
  char b;
  asm volatile ("" : "+fm<rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggx<gT,ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" (b));
  {
    try {
    } catch (char ()) {
    }
  }
}

Output:

$ xgcc -x c++ -S -std=c++14 -O3 -fpermissive -fno-toplevel-reorder -
during RTL pass: reload
<stdin>: In function 'void a()':
<stdin>:9:1: internal compiler error: in process_alt_operands, at lra-constraints.c:2112
0x289cf5b process_alt_operands
        /home/vegard/git/gcc/gcc/lra-constraints.c:2112
0x28a6043 curr_insn_transform
        /home/vegard/git/gcc/gcc/lra-constraints.c:3860
0x28b93b6 lra_constraints(bool)
        /home/vegard/git/gcc/gcc/lra-constraints.c:4877
0x2829984 lra(_IO_FILE*)
        /home/vegard/git/gcc/gcc/lra.c:2419
0x2608794 do_reload
        /home/vegard/git/gcc/gcc/ira.c:5465
0x2608794 execute
        /home/vegard/git/gcc/gcc/ira.c:5649

$ xgcc --version
xgcc (GCC) 8.0.1 20180306 (experimental)

Built from git 11a93d7a09b871b3b9a2eb108eb91ad83d94e070 (r258271).

This one is a bit of a weird one. It doesn't reproduce with "trunk" on godbolt.org for me and the crash itself is indeterministic. Sometimes the compiler doesn't print anything and it returns 0, sometimes it hangs after printing "during RTL pass: reload", and sometimes it gives the splat above (about 1 in every 10 runs, I'd say). I recommend running it in a loop to increase the chances of reproducing.

Valgrind shows a bunch of errors, this is the first one:

==31845== Conditional jump or move depends on uninitialised value(s)
==31845==    at 0x2757C74: sparseset_bit_p (sparseset.h:147)
==31845==    by 0x2757C74: mark_pseudo_regno_live(int) (ira-lives.c:289)
==31845==    by 0x2760800: process_bb_node_lives(ira_loop_tree_node*) (ira-lives.c:1140)
==31845==    by 0x2677F7D: ira_traverse_loop_tree(bool, ira_loop_tree_node*, void (*)(ira_loop_tree_node*), void (*)(ira_loop_tree_node*)) (ira-build.c:1806)
==31845==    by 0x276BED9: ira_create_allocno_live_ranges() (ira-lives.c:1565)
==31845==    by 0x2687F08: ira_build() (ira-build.c:3429)
==31845==    by 0x2640C54: ira (ira.c:5295)
==31845==    by 0x2640C54: (anonymous namespace)::pass_ira::execute(function*) (ira.c:5606)
==31845==    by 0x2B7EDA7: execute_one_pass(opt_pass*) (passes.c:2497)
==31845==    by 0x2B84CFB: execute_pass_list_1(opt_pass*) [clone .constprop.89] (passes.c:2586)
==31845==    by 0x2B85DA0: execute_pass_list_1 (passes.c:2587)
==31845==    by 0x2B85DA0: execute_pass_list(function*, opt_pass*) (passes.c:2597)
==31845==    by 0x19A118E: cgraph_node::expand() (cgraphunit.c:2139)
==31845==    by 0x19AA5A7: expand_all_functions (cgraphunit.c:2275)
==31845==    by 0x19AA5A7: symbol_table::compile() [clone .part.56] (cgraphunit.c:2624)
==31845==    by 0x19B84D7: compile (cgraphunit.c:2537)
==31845==    by 0x19B84D7: symbol_table::finalize_compilation_unit() (cgraphunit.c:2717)

I've attached a full valgrind log as well, in case that helps.

Test case was minimised by C-Reduce.
Comment 1 Martin Sebor 2018-03-08 04:21:15 UTC
I have reproduced it (intermittently) with revisions as recent as r258160, but only with ASLR enabled.  The valgrind errors for sparseset_bit_p are expected and go away --with-enable-valgrind-annotations.  I don't see any other errors in my report and I can't reproduce it without ASLR or under GDB so there isn't much to go on.

$ /opt/notnfs/gcc-bisect/obj/gcc/cc1plus.258160 -quiet -O3 -fpermissive -fno-toplevel-reorder -std=c++14 -o/dev/null t.C
during RTL pass: reload
t.C: In function ‘void a()’:
t.C:10:1: internal compiler error: in process_alt_operands, at lra-constraints.c:2112
 }
 ^
0x1013ddb process_alt_operands
	../../gcc/lra-constraints.c:2112
0x10187ca curr_insn_transform
	../../gcc/lra-constraints.c:3860
0x101c13f lra_constraints(bool)
	../../gcc/lra-constraints.c:4877
0x1004f6f lra(_IO_FILE*)
	../../gcc/lra.c:2419
0xfac579 do_reload
	../../gcc/ira.c:5465
0xfaca6c execute
	../../gcc/ira.c:5649
Comment 2 Vegard Nossum 2018-03-08 11:36:10 UTC
Created attachment 43598 [details]
ASAN output

I compiled gcc itself using -fstack-protector-all -fsanitize=address and it occasionally gives me the "heap-use-after-free" error (log attached).
Comment 3 Vegard Nossum 2018-03-08 11:55:45 UTC
gcc/recog.c:2395 is:

2390 case '0': case '1': case '2': case '3': case '4':
2391 case '5': case '6': case '7': case '8': case '9':
2392   {
2393     char *end;
2394     op_alt[i].matches = strtoul (p, &end, 10);
2395     op_alt[op_alt[i].matches].matched = i;
2396     p = end;
2397   }
2398   continue;

It's a bit weird because I don't see any digits in the constraints in the test case.
Comment 4 Vegard Nossum 2018-03-08 12:22:33 UTC
So I think the problem is that this loop in lra_set_insn_recog_data() counts the number of commas and uses that as the number of alternatives:

1018               for (p =  constraints[0]; *p; p++)
1019                 nalt += *p == ',';

And then later we can skip over the comma inside preprocess_constraints() because 'T' is not recognised in the switch and then it does:

p += CONSTRAINT_LEN (c, p);

where CONSTRAINT_LEN for 'T' is 2:

static inline size_t
insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)
{
  switch (fc)
    {
    case 'B': return 2;
    case 'T': return 2;
    case 'W': return 2;
    case 'Y': return 2;
    default: break;
    }
  return 1;
}

(so the real problematic bit of the constraint is this: "T,")
Comment 5 Jakub Jelinek 2018-03-08 13:19:45 UTC
We have many loops that assume the constraints are sane and it is safe to skip all the CONSTRAINT_LEN characters, so I think it is desirable to catch this early.
asm_operand_ok already has:
      len = CONSTRAINT_LEN (c, constraint);
      do
        constraint++;
      while (--len && *constraint);
      if (len)
        return 0;
which catches multi-character constraints with '\0' in the middle of it, and rejects those during vregs pass that also removes them:
  if (asm_noperands (PATTERN (insn)) >= 0)
    {
      if (!check_asm_operands (PATTERN (insn)))
        {
          error_for_asm (insn, "impossible constraint in %<asm%>");
          /* For asm goto, instead of fixing up all the edges
             just clear the template and clear input operands
             (asm goto doesn't have any output operands).  */
          if (JUMP_P (insn))
            {
              rtx asm_op = extract_asm_operands (PATTERN (insn));
              ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
              ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
              ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
            }
          else
            delete_insn (insn);
        }
    }
So I'm just adding a check for ',' inside such constraints too.
Comment 6 Jakub Jelinek 2018-03-08 13:30:28 UTC
Created attachment 43599 [details]
gcc8-pr84742.patch

Untested fix.
Comment 7 Jakub Jelinek 2018-03-08 20:55:35 UTC
Author: jakub
Date: Thu Mar  8 20:55:03 2018
New Revision: 258369

URL: https://gcc.gnu.org/viewcvs?rev=258369&root=gcc&view=rev
Log:
	PR inline-asm/84742
	* recog.c (asm_operand_ok): Return 0 if multi-character constraint
	has ',' character inside of it.

	* gcc.target/i386/pr84742-1.c: New test.
	* gcc.target/i386/pr84742-2.c: New test.

Added:
    trunk/gcc/testsuite/gcc.target/i386/pr84742-1.c
    trunk/gcc/testsuite/gcc.target/i386/pr84742-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/recog.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2018-03-08 20:56:47 UTC
Fixed.