It turns out (all from krister, I am still totally lost) that it is not failing for this specific reason in this case.
Rather, the attached patch from krister fixes it, saying that gcc wants to change the label and then doesn't recognise the new insn thinking the memory_operand predicate is not satisfied. The new predicate is from rs6000. In retrospect the most important thing to provide was the 4 line shell script to reproduce the problem, I felt uneasy sharing that because it is with netbsd's copy of GCC (which I know how to cross-build). For the purpose of changing it to support a reversed pc/label_ref, I can probably cargo-cult make it look like branch and make the square peg fit in a round hole by a lot experimenting, but I don't understand the code I have to be changing to do that. There is this construct in the code that I don't understand why I want to do anything like it, even if I can parse what the individual parts of it mean: (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") (const_int 1) (match_dup 1)) (const_int 1))])]
diff --git a/external/gpl3/gcc/dist/gcc/config/vax/builtins.md b/external/gpl3/gcc/dist/gcc/config/vax/builtins.md index 7be1179..5fb6da6 100644 --- a/external/gpl3/gcc/dist/gcc/config/vax/builtins.md +++ b/external/gpl3/gcc/dist/gcc/config/vax/builtins.md @@ -77,13 +77,13 @@ [(parallel [(set (pc) (if_then_else - (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "g") + (ne (zero_extract:SI (match_operand:QI 0 "volatile_mem_operand" "g") (const_int 1) (match_operand:SI 1 "general_operand" "nrm")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:QI 3 "volatile_mem_operand" "+0") (const_int 1) (match_dup 1)) (const_int 1))])] @@ -94,13 +94,13 @@ [(parallel [(set (pc) (if_then_else - (ne (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q") + (ne (zero_extract:SI (match_operand:HI 0 "volatile_mem_operand" "Q") (const_int 1) (match_operand:SI 1 "general_operand" "nrm")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:HI 3 "volatile_mem_operand" "+0") (const_int 1) (match_dup 1)) (const_int 1))])] @@ -111,13 +111,13 @@ [(parallel [(set (pc) (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q") + (ne (zero_extract:SI (match_operand:SI 0 "volatile_mem_operand" "Q") (const_int 1) (match_operand:SI 1 "general_operand" "nrm")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:SI 3 "volatile_mem_operand" "+0") (const_int 1) (match_dup 1)) (const_int 1))])] diff --git a/external/gpl3/gcc/dist/gcc/config/vax/predicates.md b/external/gpl3/gcc/dist/gcc/config/vax/predicates.md index 7344192..f68c3f4 100644 --- a/external/gpl3/gcc/dist/gcc/config/vax/predicates.md +++ b/external/gpl3/gcc/dist/gcc/config/vax/predicates.md @@ -109,3 +109,16 @@ (and (match_code "const_int,const_double,subreg,reg,mem") (and (match_operand:DI 0 "general_operand" "") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand"))))) + +;; Return 1 if the operand is in volatile memory. Note that during the +;; RTL generation phase, memory_operand does not return TRUE for volatile +;; memory references. So this function allows us to recognize volatile +;; references where it's safe. +(define_predicate "volatile_mem_operand" + (and (and (match_code "mem") + (match_test "MEM_VOLATILE_P (op)")) + (if_then_else (match_test "reload_completed") + (match_operand 0 "memory_operand") + (if_then_else (match_test "reload_in_progress") + (match_test "strict_memory_address_p (mode, XEXP (op, 0))") + (match_test "memory_address_p (mode, XEXP (op, 0))")))))