public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 10:55   ` Eric Botcazou
  2020-11-20  3:34 ` [PATCH 02/31] VAX: Remove `c' operand format specifier overload Maciej W. Rozycki
                   ` (33 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

From: Matt Thomas <matt@3am-software.com>

Fix an ICE with the handling of RTL expressions like:

(subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67])
                    (const_int 4 [0x4]))
                (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59]))
            (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0)

that causes the compilation of libgomp to fail:

during RTL pass: reload
.../libgomp/ordered.c: In function 'GOMP_doacross_wait':
.../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
  507 | }
      | ^
0x10a3462b change_address_1
	.../gcc/emit-rtl.c:2275
0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
	.../gcc/emit-rtl.c:2409
0x10ae2993 alter_subreg(rtx_def**, bool)
	.../gcc/final.c:3368
0x10ae25cf cleanup_subreg_operands(rtx_insn*)
	.../gcc/final.c:3322
0x110922a3 reload(rtx_insn*, int)
	.../gcc/reload1.c:1232
0x10de2bf7 do_reload
	.../gcc/ira.c:5812
0x10de3377 execute
	.../gcc/ira.c:5986

in a `vax-netbsdelf' build, where an attempt is made to change the mode
of the contained memory reference to the mode of the containing SUBREG.
Such RTL expressions are produced by the VAX shift and rotate patterns
(`ashift', `ashiftrt', `rotate', `rotatert') where the count operand
always has the QI mode regardless of the mode, either SI or DI, of the
datum shifted or rotated.

Such a mode change cannot work where the memory reference uses the
indexed addressing mode, where a multiplier is implied that in the VAX
ISA depends on the width of the memory access requested and therefore
changing the machine mode would change the address calculation as well.

Avoid the attempt then by forcing the reload of any SUBREGs containing
a mode-dependent memory reference, also fixing these regressions:

FAIL: gcc.c-torture/compile/pr46883.c   -Os  (internal compiler error)
FAIL: gcc.c-torture/compile/pr46883.c   -Os  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
FAIL: gcc.dg/20050629-1.c (internal compiler error)
FAIL: gcc.dg/20050629-1.c (test for excess errors)
FAIL: c-c++-common/torture/pr53505.c   -Os  (internal compiler error)
FAIL: c-c++-common/torture/pr53505.c   -Os  (test for excess errors)
FAIL: gfortran.dg/coarray_failed_images_1.f08   -Os  (internal compiler error)
FAIL: gfortran.dg/coarray_stopped_images_1.f08   -Os  (internal compiler error)

First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.

	gcc/
	PR target/58901
	* reload.c (reload_inner_reg_of_subreg): Also request reloading
	for pseudo registers associated with mode dependent memory
	references.
	(push_reload): Handle pseudo registers.
---
 gcc/reload.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/gcc/reload.c b/gcc/reload.c
index 445f9bdca43..dbf83733815 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -838,6 +838,7 @@ static bool
 reload_inner_reg_of_subreg (rtx x, machine_mode mode, bool output)
 {
   rtx inner;
+  int regno;
 
   /* Only SUBREGs are problematical.  */
   if (GET_CODE (x) != SUBREG)
@@ -849,10 +850,21 @@ reload_inner_reg_of_subreg (rtx x, machine_mode mode, bool output)
   if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
     return true;
 
-  /* If INNER is not a hard register, then INNER will not need reloading.  */
-  if (!(REG_P (inner) && HARD_REGISTER_P (inner)))
+  /* If INNER is not a register, then INNER will not need reloading.  */
+  if (!REG_P (inner))
     return false;
 
+  regno = REGNO (inner);
+
+  /* If INNER is not a hard register, then INNER will not need reloading
+     unless it's a mode dependent memory reference.  */
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    return (!output
+	    && reg_equiv_mem (regno) != 0
+	    && (mode_dependent_address_p
+		(XEXP (reg_equiv_mem (regno), 0),
+		 MEM_ADDR_SPACE (reg_equiv_mem (regno)))));
+
   /* If INNER is not ok for MODE, then INNER will need reloading.  */
   if (!targetm.hard_regno_mode_ok (subreg_regno (x), mode))
     return true;
@@ -1119,7 +1131,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
   if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
     {
-      if (REG_P (SUBREG_REG (in)))
+      if (REG_P (SUBREG_REG (in)) && HARD_REGISTER_P (SUBREG_REG (in)))
 	subreg_in_class
 	  = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)),
 			      subreg_regno_offset (REGNO (SUBREG_REG (in)),
@@ -1127,8 +1139,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 						   SUBREG_BYTE (in),
 						   GET_MODE (in)),
 			      REGNO (SUBREG_REG (in)));
-      else if (CONSTANT_P (SUBREG_REG (in))
-               || GET_CODE (SUBREG_REG (in)) == PLUS)
+      else if (REG_P (SUBREG_REG (in))
+	       || CONSTANT_P (SUBREG_REG (in))
+	       || GET_CODE (SUBREG_REG (in)) == PLUS)
 	subreg_in_class = find_valid_class_1 (inmode,
 					      GET_MODE (SUBREG_REG (in)),
 					      rclass);
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 02/31] VAX: Remove `c' operand format specifier overload
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
  2020-11-20  3:34 ` [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 23:16   ` Jeff Law
  2020-11-24  1:12   ` Segher Boessenkool
  2020-11-20  3:34 ` [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P Maciej W. Rozycki
                   ` (32 subsequent siblings)
  34 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The `c' operand format specifier is handled directly by the middle end
in `output_asm_insn':

   %cN means require operand N to be a constant
      and print the constant expression with no punctuation.

however it resorts to the target for constants that are not valid
addresses:

	    else if (letter == 'c')
	      {
		if (CONSTANT_ADDRESS_P (operands[opnum]))
		  output_addr_const (asm_out_file, operands[opnum]);
		else
		  output_operand (operands[opnum], 'c');
	      }

The VAX backend expects the fallback never to happen and overloads `c'
with the branch condition code.  This is confusing however and it is not
like we are short of letters, so instead make the branch condition code
use `k', and then for consistency make `K' the reverse branch condition
code format specifier.  This is safe to do as we provide no means to use
a computed branch condition code in user `asm'.

	gcc/
	* config/vax/vax.c (print_operand): Replace `c' and `C' with
	`k' and `K' respectively.
	* config/vax/vax.md (*branch, *branch_reversed): Update
	accordingly.
---
 gcc/config/vax/vax.c  | 4 ++--
 gcc/config/vax/vax.md | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index da4e6cb1745..0b3b76ed6da 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -509,9 +509,9 @@ print_operand (FILE *file, rtx x, int code)
     fputc (ASM_DOUBLE_CHAR, file);
   else if (code == '|')
     fputs (REGISTER_PREFIX, file);
-  else if (code == 'c')
+  else if (code == 'k')
     fputs (cond_name (x), file);
-  else if (code == 'C')
+  else if (code == 'K')
     fputs (rev_cond_name (x), file);
   else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0)
     fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x));
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 4897ce44505..e3018a0ee06 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -1111,7 +1111,7 @@ (define_insn "*branch"
 		      (label_ref (match_operand 1 "" ""))
 		      (pc)))]
   ""
-  "j%c0 %l1")
+  "j%k0 %l1")
 
 ;; Recognize reversed jumps.
 (define_insn "*branch_reversed"
@@ -1122,7 +1122,7 @@ (define_insn "*branch_reversed"
 		      (pc)
 		      (label_ref (match_operand 1 "" ""))))]
   ""
-  "j%C0 %l1") ; %C0 negates condition
+  "j%K0 %l1") ; %K0 negates condition
 \f
 ;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
 ;; of jlbs and jlbc insns are SImode in the hardware.  However, if it is
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
  2020-11-20  3:34 ` [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Maciej W. Rozycki
  2020-11-20  3:34 ` [PATCH 02/31] VAX: Remove `c' operand format specifier overload Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-21  3:17   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels Maciej W. Rozycki
                   ` (31 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The VAX ELF psABI does not permit the use of all hardware operand modes
for PIC symbol references due to the need to use PC-relative addressing
for symbols that end up local and the need to make references indirect
symbols that end up global.

Therefore symbols referred as immediates may only be used with the move
and push address (MOVA and PUSHA) instructions and their PC-relative
displacement address mode, as there is no genuine PC-relative immediate
available that all the other instructions would have to use.

Furthermore global symbol references must not have an offset applied,
which has to be added with a separate instruction, because there is no
support now for GOT entries for external `symbol+offset' references, so
any indirect GOT references made by the static linker from the original
direct symbol references must not have an addend applied.  Consequently
no addend is allowed even if a given external symbol turns out local,
for whatever reason, at the static link time.

Define the LEGITIMATE_PIC_OPERAND_P macro then, a corresponding function
and predicate to exclude the relevant expressions as required, and then
a constraint so that reloads are produced where needed, and use the new
facilities in the machine description, folding corresponding duplicated
patterns for local and external symbols together.  Rewrite predicates to
make use of the new function, rename them to match their sense and also
remove ones no longer used.

All this fixing an ICE like this:

during RTL pass: postreload
.../gcc/testsuite/gcc.c-torture/execute/20040709-2.c: In function 'testE':
.../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:89:1: internal compiler error: in reload_combine_note_use, at postreload.c:1559
.../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:96:65: note: in expansion of macro 'T'
0x10fe84cb reload_combine_note_use
	.../gcc/postreload.c:1559
0x10fe8857 reload_combine_note_use
	.../gcc/postreload.c:1621
0x10fe8303 reload_combine_note_use
	.../gcc/postreload.c:1517
0x10fe7c7b reload_combine
	.../gcc/postreload.c:1408
0x10fe3417 reload_cse_regs
	.../gcc/postreload.c:67
0x10feaf9f execute
	.../gcc/postreload.c:2358

due to the presence of a pseudo register post-reload:

(insn 435 228 229 13 (set (reg:SI 1 %r1)
        (mem/c:SI (reg/f:SI 341) [25 sE+12 S4 A8])) ".../gcc/testsuite/gcc.c-torture/execute/20040709-2.c":96:65 12 {movsi_2}
     (nil))

(due to the use of an offset `sE+12' symbol reference) and removing
these regressions:

FAIL: gcc.c-torture/execute/20040709-2.c   -O2  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-2.c   -O2  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -g  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-2.c   -Os  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-2.c   -Os  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-3.c   -O2  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-3.c   -O2  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-3.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-3.c   -O3 -g  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-3.c   -Os  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-3.c   -Os  (test for excess errors)
FAIL: gcc.c-torture/execute/20040709-3.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
FAIL: gcc.c-torture/execute/20040709-3.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: gcc.dg/torture/pr52028.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
FAIL: gcc.dg/torture/pr52028.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)

	gcc/
	* config/vax/constraints.md (A): New constraint.
	* config/vax/predicates.md (external_symbolic_operand)
	(external_const_operand): Remove predicates.
	(local_symbolic_operand): Rename to...
	(pic_symbolic_operand): ... this, and rework.
	(external_memory_operand): Rename to...
	(non_pic_external_memory_operand): ... this, and rework.
	(illegal_blk_memory_operand, illegal_addsub_di_memory_operand):
	Update accordingly.
	* config/vax/vax-protos.h (vax_acceptable_pic_operand_p): New
	prototype.
	* config/vax/vax.c (vax_acceptable_pic_operand_p): New function.
	(vax_output_int_add): Update according to predicate rework.
	* config/vax/vax.h (LEGITIMATE_PIC_OPERAND_P): New macro.
	* config/vax/vax.md (pushlclsymreg, pushextsymreg): Fold
	together, and rename to...
	(*pushsymreg): ... this.  Use the `pic_symbolic_operand'
	predicate and the `A' constraint for the displacement operand.
	(movlclsymreg, movextsymreg): Fold together, and rename to...
	(*movsymreg): ... this.  Use the `pic_symbolic_operand'
	predicate and the `A' constraint for the displacement operand.
	(pushextsym, pushlclsym): Fold together, and rename to...
	(*pushsym): ... this.  Use the `pic_symbolic_operand' predicate
	and the `A' constraint for the displacement operand.
	(movextsym, movlclsym): Fold together, and rename to...
	(*movsym): ... this.  Use the `pic_symbolic_operand' predicate
	and the `A' constraint for the displacement operand.
---
 gcc/config/vax/constraints.md |  4 ++++
 gcc/config/vax/predicates.md  | 34 ++++++++-------------------
 gcc/config/vax/vax-protos.h   |  1 +
 gcc/config/vax/vax.c          | 39 +++++++++++++++++++++++++++++--
 gcc/config/vax/vax.h          |  5 ++++
 gcc/config/vax/vax.md         | 54 +++++++++++--------------------------------
 6 files changed, 70 insertions(+), 67 deletions(-)

diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md
index b8262b6da6f..d4eddb82a66 100644
--- a/gcc/config/vax/constraints.md
+++ b/gcc/config/vax/constraints.md
@@ -112,6 +112,10 @@ (define_memory_constraint "R"
     (and (match_operand:DI 0 "memory_operand")
 	 (not (match_operand:DI 0 "illegal_addsub_di_memory_operand" ""))))
 
+(define_constraint "A"
+    "@internal An integer constant suitable for address load operations."
+  (match_test ("CONSTANT_P (op) && pic_symbolic_operand (op, mode)")))
+
 (define_constraint "T"
     "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST."
   (and (match_test ("CONSTANT_P (op)"))
diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md
index 7eefc605e98..93e91e499a6 100644
--- a/gcc/config/vax/predicates.md
+++ b/gcc/config/vax/predicates.md
@@ -23,33 +23,17 @@
 (define_predicate "symbolic_operand"
   (match_code "const,symbol_ref,label_ref"))
 
-(define_predicate "local_symbolic_operand"
-  (match_code "const,symbol_ref,label_ref")
-{
-  if (GET_CODE (op) == LABEL_REF)
-    return 1;
-  if (GET_CODE (op) == SYMBOL_REF)
-    return !flag_pic || SYMBOL_REF_LOCAL_P (op);
-  if (GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF)
-    return 1;
-  return !flag_pic || SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0));
-})
-
-(define_predicate "external_symbolic_operand"
-  (and (match_code "symbol_ref")
-       (not (match_operand 0 "local_symbolic_operand" ""))))
-
-(define_predicate "external_const_operand"
-  (and (match_code "const")
-       (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
-		    && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0))")))
+(define_predicate "pic_symbolic_operand"
+  (and (match_code "const,symbol_ref,label_ref")
+       (match_test "!flag_pic
+		    || vax_acceptable_pic_operand_p (op, false, true)")))
 
 (define_predicate "nonsymbolic_operand"
   (and (ior (match_test "!flag_pic")
 	    (not (match_operand 0 "symbolic_operand")))
        (match_operand 0 "general_operand" "")))
 
-(define_predicate "external_memory_operand"
+(define_predicate "non_pic_external_memory_operand"
    (match_code "mem")
 {
   rtx addr = XEXP (op, 0);
@@ -61,8 +45,8 @@ (define_predicate "external_memory_operand"
     addr = XEXP (addr, 0);
   if (GET_CODE (addr) == PLUS)
     addr = XEXP (addr, 1);
-  return external_symbolic_operand (addr, SImode)
-	 || external_const_operand (addr, SImode);
+  return (symbolic_operand (addr, SImode)
+	  && !vax_acceptable_pic_operand_p (addr, true, true));
 })
 
 (define_predicate "indirect_memory_operand"
@@ -87,7 +71,7 @@ (define_predicate "indexed_memory_operand"
 (define_predicate "illegal_blk_memory_operand"
    (and (match_code "mem")
 	(ior (and (match_test "flag_pic")
-		  (match_operand 0 "external_memory_operand" ""))
+		  (match_operand 0 "non_pic_external_memory_operand" ""))
 	     (ior (match_operand 0 "indexed_memory_operand" "")
 		  (ior (match_operand 0 "indirect_memory_operand" "")
 		       (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC"))))))
@@ -95,7 +79,7 @@ (define_predicate "illegal_blk_memory_operand"
 (define_predicate "illegal_addsub_di_memory_operand"
    (and (match_code "mem")
 	(ior (and (match_test "flag_pic")
-		  (match_operand 0 "external_memory_operand" ""))
+		  (match_operand 0 "non_pic_external_memory_operand" ""))
 	     (ior (match_operand 0 "indexed_memory_operand" "")
 		  (ior (match_operand 0 "indirect_memory_operand" "")
 		       (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC"))))))
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index cda2544f7d5..454d35e3383 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -21,6 +21,7 @@ extern bool legitimate_constant_address_p (rtx);
 extern void vax_expand_prologue (void);
 
 #ifdef RTX_CODE
+extern bool vax_acceptable_pic_operand_p (rtx, bool, bool);
 extern const char *cond_name (rtx);
 extern bool adjacent_operands_p (rtx, rtx, machine_mode);
 extern const char *rev_cond_name (rtx);
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 0b3b76ed6da..37f5dadc74c 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -1033,6 +1033,39 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
   return true;
 }
 \f
+/* With ELF we do not support GOT entries for external `symbol+offset'
+   references, so do not accept external symbol references if an offset
+   is to be added.  Do not accept external symbol references at all if
+   LOCAL_P is set.  This is for cases where making a reference indirect
+   would make it invalid.  Do not accept any kind of symbols if SYMBOL_P
+   is clear.  This is for situations where the a reference is used as an
+   immediate value for operations other than address loads (MOVA/PUSHA),
+   as those operations do not support PC-relative immediates.  */
+
+bool
+vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED,
+			      bool local_p ATTRIBUTE_UNUSED,
+			      bool symbol_p ATTRIBUTE_UNUSED)
+{
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
+    {
+      x = XEXP (XEXP (x, 0), 0);
+      local_p = true;
+    }
+  switch (GET_CODE (x))
+    {
+    case SYMBOL_REF:
+      return symbol_p && !(local_p && !SYMBOL_REF_LOCAL_P (x));
+    case LABEL_REF:
+      return symbol_p && !(local_p && LABEL_REF_NONLOCAL_P (x));
+    default:
+      break;
+    }
+#endif
+  return true;
+}
+\f
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.
 	.mask	^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>  #conservative entry mask
@@ -1370,8 +1403,10 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode)
 	  {
 	    gcc_assert (rtx_equal_p (operands[0], operands[1]));
 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
-	    gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode));
-	    gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode));
+	    gcc_assert (!flag_pic
+			|| !non_pic_external_memory_operand (low[2], SImode));
+	    gcc_assert (!flag_pic
+			|| !non_pic_external_memory_operand (low[0], SImode));
 #endif
 
 	    /* No reason to add a 0 to the low part and thus no carry, so just
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index c1d0171d94d..146b0a6e2b2 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -442,6 +442,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    of a shift count.  */
 /* #define SHIFT_COUNT_TRUNCATED */
 
+/* We need to reject symbol references in PIC code except for address
+   loads, handled elsewhere.  */
+#define LEGITIMATE_PIC_OPERAND_P(x)	\
+  vax_acceptable_pic_operand_p ((x), false, false)
+
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index e3018a0ee06..e6b217fd0d7 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -338,34 +338,6 @@ (define_insn "add<mode>3"
    add<VAXfp:fsfx>2 %1,%0
    add<VAXfp:fsfx>3 %1,%2,%0")
 
-(define_insn "pushlclsymreg"
-  [(set (match_operand:SI 0 "push_operand" "=g")
-	(plus:SI (match_operand:SI 1 "register_operand" "%r")
-		 (match_operand:SI 2 "local_symbolic_operand" "i")))]
-  "flag_pic"
-  "pushab %a2[%1]")
-
-(define_insn "pushextsymreg"
-  [(set (match_operand:SI 0 "push_operand" "=g")
-	(plus:SI (match_operand:SI 1 "register_operand" "%r")
-		 (match_operand:SI 2 "external_symbolic_operand" "i")))]
-  "flag_pic"
-  "pushab %a2[%1]")
-
-(define_insn "movlclsymreg"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(plus:SI (match_operand:SI 1 "register_operand" "%r")
-		 (match_operand:SI 2 "local_symbolic_operand" "i")))]
-  "flag_pic"
-  "movab %a2[%1],%0")
-
-(define_insn "movextsymreg"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(plus:SI (match_operand:SI 1 "register_operand" "%r")
-		 (match_operand:SI 2 "external_symbolic_operand" "i")))]
-  "flag_pic"
-  "movab %a2[%1],%0")
-
 (define_insn "add<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
 	(plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
@@ -1525,29 +1497,31 @@ (define_insn "casesi1"
   ""
   "casel %0,$0,%1")
 \f
-(define_insn "pushextsym"
+(define_insn "*pushsym"
   [(set (match_operand:SI 0 "push_operand" "=g")
-	(match_operand:SI 1 "external_symbolic_operand" "i"))]
+	(match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
   "pushab %a1")
 
-(define_insn "movextsym"
+(define_insn "*movsym"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(match_operand:SI 1 "external_symbolic_operand" "i"))]
+	(match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
   "movab %a1,%0")
 
-(define_insn "pushlclsym"
+(define_insn "*pushsymreg"
   [(set (match_operand:SI 0 "push_operand" "=g")
-	(match_operand:SI 1 "local_symbolic_operand" "i"))]
-  ""
-  "pushab %a1")
+	(plus:SI (match_operand:SI 1 "register_operand" "%r")
+		 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
+  "flag_pic"
+  "pushab %a2[%1]")
 
-(define_insn "movlclsym"
+(define_insn "*movsymreg"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(match_operand:SI 1 "local_symbolic_operand" "i"))]
-  ""
-  "movab %a1,%0")
+	(plus:SI (match_operand:SI 1 "register_operand" "%r")
+		 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
+  "flag_pic"
+  "movab %a2[%1],%0")
 \f
 ;;- load or push effective address
 ;; These come after the move and add/sub patterns
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (2 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 23:17   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 05/31] VAX: Rationalize expression and address costs Maciej W. Rozycki
                   ` (30 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

It makes sense to use what other targets do and run all the VAX test
cases over all the usual optimization levels, so make `vax.exp' use our
`gcc-dg-runtest' rather than the generic `dg-runtest' test driver.

This breaks `pr56875.c' however, which is optimized away at levels above
`-O0' as a result of how it has been written for calculations to make no
effect:

FAIL: gcc.target/vax/pr56875.c   -O1   scan-assembler ashq .*,\\$0xffffffffffffffff,
FAIL: gcc.target/vax/pr56875.c   -O2   scan-assembler ashq .*,\\$0xffffffffffffffff,
FAIL: gcc.target/vax/pr56875.c   -O3 -g   scan-assembler ashq .*,\\$0xffffffffffffffff,
FAIL: gcc.target/vax/pr56875.c   -Os   scan-assembler ashq .*,\\$0xffffffffffffffff,
FAIL: gcc.target/vax/pr56875.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none   scan-assembler ashq .*,\\$0xffffffffffffffff,
FAIL: gcc.target/vax/pr56875.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects   scan-assembler ashq .*,\\$0xffffffffffffffff,

Rather than keeping it at `-O0' update the test case for its code to do
make effect while retaining its sense.  Also reformat it according to
our requirements.

	gcc/testsuite/
	* gcc.target/vax/vax.exp: Use `gcc-dg-runtest' rather than
	`dg-runtest'.
	* gcc.target/vax/pr56875.c (dg-options): Make empty.
	(a): Rewrite for calculations to make effect.  Reformat.
---
 gcc/testsuite/gcc.target/vax/pr56875.c | 11 ++++-------
 gcc/testsuite/gcc.target/vax/vax.exp   |  2 +-
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/vax/pr56875.c b/gcc/testsuite/gcc.target/vax/pr56875.c
index f409afe88e7..191e05e166e 100644
--- a/gcc/testsuite/gcc.target/vax/pr56875.c
+++ b/gcc/testsuite/gcc.target/vax/pr56875.c
@@ -1,13 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-O0" } */
+/* { dg-options "" } */
 /* { dg-final { scan-assembler     "ashq .*,\\\$0xffffffffffffffff," } } */
 /* { dg-final { scan-assembler-not "ashq .*,\\\$-1," } } */
 
-void
-a (void)
+unsigned long long
+a (unsigned long i)
 {
-	unsigned long i = 1;
-	unsigned long long v;
-
-	v = ~ (unsigned long long) 0 << i;
+  return ~(unsigned long long) 0 << i;
 }
diff --git a/gcc/testsuite/gcc.target/vax/vax.exp b/gcc/testsuite/gcc.target/vax/vax.exp
index 4f480559e12..678e9007686 100644
--- a/gcc/testsuite/gcc.target/vax/vax.exp
+++ b/gcc/testsuite/gcc.target/vax/vax.exp
@@ -34,7 +34,7 @@ if ![info exists DEFAULT_CFLAGS] then {
 dg-init
 
 # Main loop.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
 	"" $DEFAULT_CFLAGS
 
 # All done.
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 05/31] VAX: Rationalize expression and address costs
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (3 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-21  3:48   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin Maciej W. Rozycki
                   ` (29 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Expression costs are required to be given in terms of COSTS_N_INSNS (n),
which is defined to stand for the count of single fast instructions, and
actually returns `n * 4'.  The VAX backend however instead operates on
naked numbers, causing an anomaly for the integer const zero rtx, where
the cost given is 4 as opposed to 1 for integers in the [1:63] range, as
well as -1 for comparisons.  This is because the value of 0 returned by
`vax_rtx_costs' is converted to COSTS_N_INSNS (1) in `pattern_cost':

  return cost > 0 ? cost : COSTS_N_INSNS (1);

Consequently, where feasible, 1 or -1 are preferred over 0 by the middle
end causing code pessimization, e.g. rather than producing this:

	subl2 $4,%sp
	movl 4(%ap),%r0
	jgtr .L2
	addl2 $2,%r0
.L2:
	ret

or this:

	subl2 $4,%sp
	addl3 4(%ap),8(%ap),%r0
	jlss .L6
	addl2 $2,%r0
.L6:
	ret

code is produced like this:

	subl2 $4,%sp
	movl 4(%ap),%r0
	cmpl %r0,$1
	jgeq .L2
	addl2 $2,%r0
.L2:
	ret

or this:

	subl2 $4,%sp
	addl3 4(%ap),8(%ap),%r0
	cmpl %r0,$-1
	jleq .L6
	addl2 $2,%r0
.L6:
	ret

from this:

int
compare_mov (int x)
{
  if (x > 0)
    return x;
  else
    return x + 2;
}

and this:

int
compare_add (int x, int y)
{
  int z;

  z = x + y;
  if (z < 0)
    return z;
  else
    return z + 2;
}

respectively, which is slower and larger both at a time.

Furthermore once the backend is converted to MODE_CC this anomaly makes
it usually impossible to remove redundant comparisons in the comparison
elimination pass, because most VAX instructions set the condition codes
as per the relation of the instruction's result to 0 and not -1.

The middle end has some other assumptions as to rtx costs being given in
terms of COSTS_N_INSNS, so wrap all the VAX rtx costs then as they stand
into COSTS_N_INSNS invocations, effectively scaling the costs by 4 while
preserving their relative values, except for the integer const zero rtx
given the value of `COSTS_N_INSNS (1) / 2', half of a fast instruction
(this can be further halved if needed in the future).

Adjust address costs likewise so that they remain proportional to the
new absolute values of rtx costs.

Code size stats are as follows, collected from 17639 executables built
in `check-c' GCC testing:

              samples average  median
--------------------------------------
regressions      1420  0.400%  0.195%
unchanged       13811  0.000%  0.000%
progressions     2408 -0.504% -0.201%
--------------------------------------
total           17639 -0.037%  0.000%

with a small number of outliers only (over 5% size change):

old     new     change  %change filename
----------------------------------------------------
4991    5249     258     5.1693 981001-1.exe
2637    2777     140     5.3090 interchange-6.exe
2187    2307     120     5.4869 sprintf.x7
3969    4197     228     5.7445 pr28982a.exe
8264    8816     552     6.6795 vector-compare-1.exe
5199    5575     376     7.2321 pr28982b.exe
2113    2411     298    14.1031 20030323-1.exe
2113    2411     298    14.1031 20030323-1.exe
2113    2411     298    14.1031 20030323-1.exe

so it seems we are looking good, and we have complementing reductions
to compensate:

old     new     change  %change filename
----------------------------------------------------
2919    2631    -288    -9.8663 pr57521.exe
3427    3167    -260    -7.5868 sabd_1.exe
2985    2765    -220    -7.3701 ssad-run.exe
2985    2765    -220    -7.3701 ssad-run.exe
2985    2765    -220    -7.3701 usad-run.exe
2985    2765    -220    -7.3701 usad-run.exe
4509    4253    -256    -5.6775 vshuf-v2sf.exe
4541    4285    -256    -5.6375 vshuf-v2si.exe
4673    4417    -256    -5.4782 vshuf-v2df.exe
2993    2841    -152    -5.0785 abs-2.x4
2993    2841    -152    -5.0785 abs-3.x4

This actually causes `loop-8.c' to regress:

FAIL: gcc.dg/loop-8.c scan-rtl-dump-times loop2_invariant "Decided" 1
FAIL: gcc.dg/loop-8.c scan-rtl-dump-not loop2_invariant "without introducing a new temporary register"

but upon a closer inspection this is a red herring.  Old code looks as
follows:

	.file	"loop-8.c"
	.text
	.align 1
.globl f
	.type	f, @function
f:
	.word 0
	subl2 $4,%sp
	movl 4(%ap),%r2
	movl 8(%ap),%r3
	movl $42,(%r2)
	clrl %r0
	movl $42,%r1
	movl %r1,%r4
	jbr .L2
.L5:
	movl %r4,%r1
.L2:
	movl %r1,(%r3)[%r0]
	incl %r0
	cmpl %r0,$100
	jeql .L6
	movl $42,(%r2)[%r0]
	bicl3 $-2,%r0,%r1
	jeql .L5
	movl %r0,%r1
	jbr .L2
.L6:
	ret
	.size	f, .-f

while new one is like below:

	.file	"loop-8.c"
	.text
	.align 1
.globl f
	.type	f, @function
f:
	.word 0
	subl2 $4,%sp
	movl 4(%ap),%r2
	movl $42,(%r2)+
	movl 8(%ap),%r1
	clrl %r0
	movl $42,%r3
	movzbl $100,%r4
	movl %r3,%r5
	jbr .L2
.L5:
	movl %r5,%r3
.L2:
	movl %r3,(%r1)+
	incl %r0
	cmpl %r0,%r4
	jeql .L6
	movl $42,(%r2)+
	bicl3 $-2,%r0,%r3
	jeql .L5
	movl %r0,%r3
	jbr .L2
.L6:
	ret
	.size	f, .-f

and is clearly better: not only it is smaller, but it also uses the
post-increment rather than indexed addressing mode in the loop, of
which the former comes for free in terms of both performance and code
size while the latter causes an extra byte per operand to be produced
for the index register and also incurs an execution penalty for the
extra address calculation.

Exclude the case from VAX testing then, as already done for some other
targets and discussed with commit d242fdaec186 ("gcc.dg/loop-8.c: Skip
for mmix.").

	gcc/
	* config/vax/vax.c (vax_address_cost): Express the cost in terms
	of COSTS_N_INSNS.
	(vax_rtx_costs): Likewise.

	gcc/testsuite/
	* gcc.dg/loop-8.c: Exclude for `vax-*-*'.
	* gcc.target/vax/compare-add-zero.c: New test.
	* gcc.target/vax/compare-mov-zero.c: New test.
---
 gcc/config/vax/vax.c                            | 110 ++++++++++++------------
 gcc/testsuite/gcc.dg/loop-8.c                   |   2 +-
 gcc/testsuite/gcc.target/vax/compare-add-zero.c |  27 ++++++
 gcc/testsuite/gcc.target/vax/compare-mov-zero.c |  24 ++++++
 4 files changed, 109 insertions(+), 54 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/vax/compare-add-zero.c
 create mode 100644 gcc/testsuite/gcc.target/vax/compare-mov-zero.c

diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 37f5dadc74c..b6c2210ca6b 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -748,7 +748,7 @@ vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
 		  addr_space_t as ATTRIBUTE_UNUSED,
 		  bool speed ATTRIBUTE_UNUSED)
 {
-  return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
+  return COSTS_N_INSNS (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
 }
 
 /* Cost of an expression on a VAX.  This version has costs tuned for the
@@ -778,12 +778,13 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
     case CONST_INT:
       if (INTVAL (x) == 0)
 	{
-	  *total = 0;
+	  *total = COSTS_N_INSNS (1) / 2;
 	  return true;
 	}
       if (outer_code == AND)
 	{
-	  *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
+	  *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077
+		    ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2));
 	  return true;
 	}
       if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
@@ -792,7 +793,7 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  || ((outer_code == PLUS || outer_code == MINUS)
 	      && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
 	{
-	  *total = 1;
+	  *total = COSTS_N_INSNS (1);
 	  return true;
 	}
       /* FALLTHRU */
@@ -800,48 +801,48 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
     case CONST:
     case LABEL_REF:
     case SYMBOL_REF:
-      *total = 3;
+      *total = COSTS_N_INSNS (3);
       return true;
 
     case CONST_DOUBLE:
       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
-	*total = vax_float_literal (x) ? 5 : 8;
+	*total = vax_float_literal (x) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (8);
       else
 	*total = ((CONST_DOUBLE_HIGH (x) == 0
 		   && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
 		  || (outer_code == PLUS
 		      && CONST_DOUBLE_HIGH (x) == -1
-		      && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
-		 ? 2 : 5;
+		      && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)
+		  ? COSTS_N_INSNS (2) : COSTS_N_INSNS (5));
       return true;
 
     case POST_INC:
-      *total = 2;
-      return true;		/* Implies register operand.  */
+      *total = COSTS_N_INSNS (2);
+      return true;			/* Implies register operand.  */
 
     case PRE_DEC:
-      *total = 3;
-      return true;		/* Implies register operand.  */
+      *total = COSTS_N_INSNS (3);
+      return true;			/* Implies register operand.  */
 
     case MULT:
       switch (mode)
 	{
 	case E_DFmode:
-	  *total = 16;		/* 4 on VAX 9000 */
+	  *total = COSTS_N_INSNS (16);	/* 4 on VAX 9000 */
 	  break;
 	case E_SFmode:
-	  *total = 9;		/* 4 on VAX 9000, 12 on VAX 2 */
+	  *total = COSTS_N_INSNS (9);	/* 4 on VAX 9000, 12 on VAX 2 */
 	  break;
 	case E_DImode:
-	  *total = 16;		/* 6 on VAX 9000, 28 on VAX 2 */
+	  *total = COSTS_N_INSNS (16);	/* 6 on VAX 9000, 28 on VAX 2 */
 	  break;
 	case E_SImode:
 	case E_HImode:
 	case E_QImode:
-	  *total = 10;		/* 3-4 on VAX 9000, 20-28 on VAX 2 */
+	  *total = COSTS_N_INSNS (10);	/* 3-4 on VAX 9000, 20-28 on VAX 2 */
 	  break;
 	default:
-	  *total = MAX_COST;	/* Mode is not supported.  */
+	  *total = MAX_COST;		/* Mode is not supported.  */
 	  return true;
 	}
       break;
@@ -849,63 +850,65 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
     case UDIV:
       if (mode != SImode)
 	{
-	  *total = MAX_COST;	/* Mode is not supported.  */
+	  *total = MAX_COST;		/* Mode is not supported.  */
 	  return true;
 	}
-      *total = 17;
+      *total = COSTS_N_INSNS (17);
       break;
 
     case DIV:
       if (mode == DImode)
-	*total = 30;		/* Highly variable.  */
+	*total = COSTS_N_INSNS (30);	/* Highly variable.  */
       else if (mode == DFmode)
 	/* divide takes 28 cycles if the result is not zero, 13 otherwise */
-	*total = 24;
+	*total = COSTS_N_INSNS (24);
       else
-	*total = 11;		/* 25 on VAX 2 */
+	*total = COSTS_N_INSNS (11);	/* 25 on VAX 2 */
       break;
 
     case MOD:
-      *total = 23;
+      *total = COSTS_N_INSNS (23);
       break;
 
     case UMOD:
       if (mode != SImode)
 	{
-	  *total = MAX_COST;	/* Mode is not supported.  */
+	  *total = MAX_COST;		/* Mode is not supported.  */
 	  return true;
 	}
-      *total = 29;
+      *total = COSTS_N_INSNS (29);
       break;
 
     case FLOAT:
-      *total = (6		/* 4 on VAX 9000 */
-		+ (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode));
+      *total = COSTS_N_INSNS (6		/* 4 on VAX 9000 */
+			      + (mode == DFmode)
+			      + (GET_MODE (XEXP (x, 0)) != SImode));
       break;
 
     case FIX:
-      *total = 7;		/* 17 on VAX 2 */
+      *total = COSTS_N_INSNS (7);	/* 17 on VAX 2 */
       break;
 
     case ASHIFT:
     case LSHIFTRT:
     case ASHIFTRT:
       if (mode == DImode)
-	*total = 12;
+	*total = COSTS_N_INSNS (12);
       else
-	*total = 10;		/* 6 on VAX 9000 */
+	*total = COSTS_N_INSNS (10);	/* 6 on VAX 9000 */
       break;
 
     case ROTATE:
     case ROTATERT:
-      *total = 6;		/* 5 on VAX 2, 4 on VAX 9000 */
+      *total = COSTS_N_INSNS (6);	/* 5 on VAX 2, 4 on VAX 9000 */
       if (CONST_INT_P (XEXP (x, 1)))
 	fmt = "e"; 		/* all constant rotate counts are short */
       break;
 
     case PLUS:
     case MINUS:
-      *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
+      *total = (mode == DFmode		/* 6/8 on VAX 9000, 16/15 on VAX 2 */
+		? COSTS_N_INSNS (13) : COSTS_N_INSNS (8));
       /* Small integer operands can use subl2 and addl2.  */
       if ((CONST_INT_P (XEXP (x, 1)))
 	  && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
@@ -914,16 +917,16 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case IOR:
     case XOR:
-      *total = 3;
+      *total = COSTS_N_INSNS (3);
       break;
 
     case AND:
       /* AND is special because the first operand is complemented.  */
-      *total = 3;
+      *total = COSTS_N_INSNS (3);
       if (CONST_INT_P (XEXP (x, 0)))
 	{
 	  if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
-	    *total = 4;
+	    *total = COSTS_N_INSNS (4);
 	  fmt = "e";
 	  i = 1;
 	}
@@ -931,38 +934,38 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case NEG:
       if (mode == DFmode)
-	*total = 9;
+	*total = COSTS_N_INSNS (9);
       else if (mode == SFmode)
-	*total = 6;
+	*total = COSTS_N_INSNS (6);
       else if (mode == DImode)
-	*total = 4;
+	*total = COSTS_N_INSNS (4);
       else
-	*total = 2;
+	*total = COSTS_N_INSNS (2);
       break;
 
     case NOT:
-      *total = 2;
+      *total = COSTS_N_INSNS (2);
       break;
 
     case ZERO_EXTRACT:
     case SIGN_EXTRACT:
-      *total = 15;
+      *total = COSTS_N_INSNS (15);
       break;
 
     case MEM:
       if (mode == DImode || mode == DFmode)
-	*total = 5;		/* 7 on VAX 2 */
+	*total = COSTS_N_INSNS (5);	/* 7 on VAX 2 */
       else
-	*total = 3;		/* 4 on VAX 2 */
+	*total = COSTS_N_INSNS (3);	/* 4 on VAX 2 */
       x = XEXP (x, 0);
       if (!REG_P (x) && GET_CODE (x) != POST_INC)
-	*total += vax_address_cost_1 (x);
+	*total += COSTS_N_INSNS (vax_address_cost_1 (x));
       return true;
 
     case FLOAT_EXTEND:
     case FLOAT_TRUNCATE:
     case TRUNCATE:
-      *total = 3;		/* FIXME: Costs need to be checked  */
+      *total = COSTS_N_INSNS (3);	/* FIXME: Costs need to be checked  */
       break;
 
     default:
@@ -993,12 +996,12 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	case CONST_INT:
 	  if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
 	      && mode != QImode)
-	    *total += 1;	/* 2 on VAX 2 */
+	    *total += COSTS_N_INSNS (1);	/* 2 on VAX 2 */
 	  break;
 	case CONST:
 	case LABEL_REF:
 	case SYMBOL_REF:
-	  *total += 1;		/* 2 on VAX 2 */
+	  *total += COSTS_N_INSNS (1);		/* 2 on VAX 2 */
 	  break;
 	case CONST_DOUBLE:
 	  if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
@@ -1006,27 +1009,28 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	      /* Registers are faster than floating point constants -- even
 		 those constants which can be encoded in a single byte.  */
 	      if (vax_float_literal (op))
-		*total += 1;
+		*total += COSTS_N_INSNS (1);
 	      else
-		*total += (GET_MODE (x) == DFmode) ? 3 : 2;
+		*total += (GET_MODE (x) == DFmode
+			   ? COSTS_N_INSNS (3) : COSTS_N_INSNS (2));
 	    }
 	  else
 	    {
 	      if (CONST_DOUBLE_HIGH (op) != 0
 		  || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63)
-		*total += 2;
+		*total += COSTS_N_INSNS (2);
 	    }
 	  break;
 	case MEM:
-	  *total += 1;		/* 2 on VAX 2 */
+	  *total += COSTS_N_INSNS (1);		/* 2 on VAX 2 */
 	  if (!REG_P (XEXP (op, 0)))
-	    *total += vax_address_cost_1 (XEXP (op, 0));
+	    *total += COSTS_N_INSNS (vax_address_cost_1 (XEXP (op, 0)));
 	  break;
 	case REG:
 	case SUBREG:
 	  break;
 	default:
-	  *total += 1;
+	  *total += COSTS_N_INSNS (1);
 	  break;
 	}
     }
diff --git a/gcc/testsuite/gcc.dg/loop-8.c b/gcc/testsuite/gcc.dg/loop-8.c
index af317d80a29..90ea1c45524 100644
--- a/gcc/testsuite/gcc.dg/loop-8.c
+++ b/gcc/testsuite/gcc.dg/loop-8.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O1 -fdump-rtl-loop2_invariant" } */
-/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-*" } } */
+/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-* vax-*-*" } } */
 /* Load immediate on condition is available from z13 on and prevents moving
    the load out of the loop, so always run this test with -march=zEC12 that
    does not have load immediate on condition.  */
diff --git a/gcc/testsuite/gcc.target/vax/compare-add-zero.c b/gcc/testsuite/gcc.target/vax/compare-add-zero.c
new file mode 100644
index 00000000000..97d4c535c73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/compare-add-zero.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int
+compare_add (int x, int y)
+{
+  int z;
+
+  z = x + y;
+  if (z < 0)
+    return z;
+  else
+    return z + 2;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),8(%ap),%r0
+	jlss .L1
+	addl2 $2,%r0
+.L1:
+
+A reverse branch may be used at some optimization levels.  */
+
+/* Make sure the comparison is made against 0 rather than -1.  */
+/* { dg-final { scan-assembler-not "\tj(gtr|leq) " } } */
+/* { dg-final { scan-assembler "\tj(geq|lss) " } } */
diff --git a/gcc/testsuite/gcc.target/vax/compare-mov-zero.c b/gcc/testsuite/gcc.target/vax/compare-mov-zero.c
new file mode 100644
index 00000000000..c802049f58e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/compare-mov-zero.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int
+compare_mov (int x)
+{
+  if (x > 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0
+	jgtr .L2
+	addl2 $2,%r0
+.L2:
+
+A reverse branch may be used at some optimization levels.  */
+
+/* Make sure the comparison is made against 0 rather than 1.  */
+/* { dg-final { scan-assembler-not "\tj(geq|lss) " } } */
+/* { dg-final { scan-assembler "\tj(gtr|leq) " } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (4 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 05/31] VAX: Rationalize expression and address costs Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 23:19   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators Maciej W. Rozycki
                   ` (28 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The `builtins.md' machine description fragment is not included anywhere
and is therefore dead code, which has become bitrotten due to non-use.

If actually enabled, it does not build due to the use of an unknown `t'
constraint:

.../gcc/config/vax/builtins.md:42:1: error: undefined machine-specific constraint at this point: "t"
.../gcc/config/vax/builtins.md:42:1: note:  in operand 1

which came from commit becb93d02cc1 ("builtins.md (ffssi2_internal):
Correct constraint."), which was not applied as posted and reviewed; `T'
was meant to be used instead.

Once this has been fixed this code still fails building:

.../gcc/config/vax/builtins.md: In function 'rtx_def* gen_ffssi2(rtx, rtx)':
.../gcc/config/vax/builtins.md:35:19: error: 'gen_bne' was not declared in this
scope; did you mean 'gen_use'?
   35 |   emit_jump_insn (gen_bne (label));
      |                   ^~~~~~~
      |                   gen_use
make[2]: *** [Makefile:1122: insn-emit.o] Error 1

Finally the FFS machine instruction sets the Z condition code according
to the comparison of the value held in the source operand against zero
rather than the value held in the target operand.  If the source operand
is found hold zero, then the target operand is set to the width of the
source operand, 32 for SImode (FFS supports arbitrary widths).

Correct the build issues then and update RTL to match the operation of
the machine instruction.  A test case will be added separately.

	gcc/
	* config/vax/builtins.md (ffssi2): Make preparation statements
	actually buildable.
	(ffssi2_internal): Fix input constraints; make the RTL pattern
	match reality for `cc0'.
---
 gcc/config/vax/builtins.md | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index ac0e0271ddd..6bce7a85add 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -31,8 +31,12 @@ (define_expand "ffssi2"
   "
 {
   rtx label = gen_label_rtx ();
+  rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
+  rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
+  rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
+
   emit_insn (gen_ffssi2_internal (operands[0], operands[1]));
-  emit_jump_insn (gen_bne (label));
+  emit_jump_insn (gen_rtx_SET (pc_rtx, target));
   emit_insn (gen_negsi2 (operands[0], const1_rtx));
   emit_label (label);
   emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
@@ -41,8 +45,10 @@ (define_expand "ffssi2"
 
 (define_insn "ffssi2_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
-	(ffs:SI (match_operand:SI 1 "general_operand" "nrQt")))
-   (set (cc0) (match_dup 0))]
+	(ffs:SI (match_operand:SI 1 "general_operand" "nrQT")))
+   (set (cc0)
+	(compare (match_dup 1)
+		 (const_int 0)))]
   ""
   "ffs $0,$32,%1,%0")
 
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (5 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-21  4:19   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE Maciej W. Rozycki
                   ` (27 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Add wide integer aka 'w' rtx format support to int iterators so that
machine description can iterate over `const_int' expressions.

This is made by expanding standard integer aka 'i' format support,
observing that any standard integer already present in any of our
existing RTL code will also fit into HOST_WIDE_INT, so there is no need
for a separate handler.  Any truncation of the number parsed is made by
the caller.  An assumption is made however that no place relies on
capping out of range values to INT_MAX.

Now the 'p' format is handled explicitly rather than being implied by
rtx being a SUBREG, so actually assert that it is, just to play safe.

	gcc/
	* read-rtl.c: Add a page-feed separator at the start of iterator
	code.
	(struct iterator_group): Change the return type to HOST_WIDE_INT
	for the `find_builtin' member.  Likewise the second parameter
	type for the `apply_iterator' member.
	(atoll) [!HAVE_ATOQ]: Reorder.
	(find_mode, find_code): Change the return type to HOST_WIDE_INT.
	(apply_mode_iterator, apply_code_iterator)
	(apply_subst_iterator): Change the second parameter type to
	HOST_WIDE_INT.
	(find_int): Handle input suitable for HOST_WIDE_INT output.
	(apply_int_iterator): Rewrite in terms of explicit format
	interpretation.
	(rtx_reader::read_rtx_operand) <'w'>: Fold into...
	<'i', 'n', 'p'>: ... this.
	* doc/md.texi (Int Iterators): Document 'w' rtx format support.
---
 gcc/doc/md.texi |  10 ++--
 gcc/read-rtl.c  | 165 ++++++++++++++++++++++++++++++--------------------------
 2 files changed, 93 insertions(+), 82 deletions(-)

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 813875b973b..762a6cf050e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -11201,11 +11201,11 @@ The construct:
 @end smallexample
 
 defines a pseudo integer constant @var{name} that can be instantiated as
-@var{inti} if condition @var{condi} is true.  Each @var{int}
-must have the same rtx format.  @xref{RTL Classes}. Int iterators can appear
-in only those rtx fields that have 'i' as the specifier. This means that
-each @var{int} has to be a constant defined using define_constant or
-define_c_enum.
+@var{inti} if condition @var{condi} is true.  Each @var{int} must have the
+same rtx format.  @xref{RTL Classes}.  Int iterators can appear in only
+those rtx fields that have 'i', 'n', 'w', or 'p' as the specifier.  This
+means that each @var{int} has to be a constant defined using define_constant
+or define_c_enum.
 
 As with mode and code iterators, each pattern that uses @var{name} will be
 expanded @var{n} times, once with all uses of @var{name} replaced by
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 3ec83a60baf..403f254f3cb 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -77,12 +77,12 @@ struct iterator_group {
 
   /* Treat the given string as the name of a standard mode, etc., and
      return its integer value.  */
-  int (*find_builtin) (const char *);
+  HOST_WIDE_INT (*find_builtin) (const char *);
 
   /* Make the given rtx use the iterator value given by the third argument.
      If the iterator applies to operands, the second argument gives the
      operand index, otherwise it is ignored.  */
-  void (*apply_iterator) (rtx, unsigned int, int);
+  void (*apply_iterator) (rtx, unsigned int, HOST_WIDE_INT);
 
   /* Return the C token for the given standard mode, code, etc.  */
   const char *(*get_c_token) (int);
@@ -139,7 +139,7 @@ static void one_time_initialization (void);
 
 /* Global singleton.  */
 rtx_reader *rtx_reader_ptr = NULL;
-
+\f
 /* The mode and code iterator structures.  */
 static struct iterator_group modes, codes, ints, substs;
 
@@ -152,9 +152,49 @@ static vec<iterator_use> iterator_uses;
 /* The list of all attribute uses in the current rtx.  */
 static vec<attribute_use> attribute_uses;
 
+/* Provide a version of a function to read a long long if the system does
+   not provide one.  */
+#if (HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG			\
+     && !HAVE_DECL_ATOLL						\
+     && !defined (HAVE_ATOQ))
+HOST_WIDE_INT atoll (const char *);
+
+HOST_WIDE_INT
+atoll (const char *p)
+{
+  int neg = 0;
+  HOST_WIDE_INT tmp_wide;
+
+  while (ISSPACE (*p))
+    p++;
+  if (*p == '-')
+    neg = 1, p++;
+  else if (*p == '+')
+    p++;
+
+  tmp_wide = 0;
+  while (ISDIGIT (*p))
+    {
+      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
+      if (new_wide < tmp_wide)
+	{
+	  /* Return INT_MAX equiv on overflow.  */
+	  tmp_wide = HOST_WIDE_INT_M1U >> 1;
+	  break;
+	}
+      tmp_wide = new_wide;
+      p++;
+    }
+
+  if (neg)
+    tmp_wide = -tmp_wide;
+  return tmp_wide;
+}
+#endif
+
 /* Implementations of the iterator_group callbacks for modes.  */
 
-static int
+static HOST_WIDE_INT
 find_mode (const char *name)
 {
   int i;
@@ -167,7 +207,7 @@ find_mode (const char *name)
 }
 
 static void
-apply_mode_iterator (rtx x, unsigned int, int mode)
+apply_mode_iterator (rtx x, unsigned int, HOST_WIDE_INT mode)
 {
   PUT_MODE (x, (machine_mode) mode);
 }
@@ -215,7 +255,7 @@ maybe_find_code (const char *name)
 
 /* Implementations of the iterator_group callbacks for codes.  */
 
-static int
+static HOST_WIDE_INT
 find_code (const char *name)
 {
   rtx_code code = maybe_find_code (name);
@@ -225,7 +265,7 @@ find_code (const char *name)
 }
 
 static void
-apply_code_iterator (rtx x, unsigned int, int code)
+apply_code_iterator (rtx x, unsigned int, HOST_WIDE_INT code)
 {
   PUT_CODE (x, (enum rtx_code) code);
 }
@@ -245,20 +285,52 @@ get_code_token (int code)
    we have to accept any int as valid.  No cross-checking can
    be done.  */
 
-static int
+static HOST_WIDE_INT
 find_int (const char *name)
 {
+  HOST_WIDE_INT tmp;
+
   validate_const_int (name);
-  return atoi (name);
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+  tmp = atoi (name);
+#else
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+  tmp = atol (name);
+#else
+  /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
+     But prefer not to use our hand-rolled function above either.  */
+#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
+  tmp = atoll (name);
+#else
+  tmp = atoq (name);
+#endif
+#endif
+#endif
+  return tmp;
 }
 
 static void
-apply_int_iterator (rtx x, unsigned int index, int value)
+apply_int_iterator (rtx x, unsigned int index, HOST_WIDE_INT value)
 {
-  if (GET_CODE (x) == SUBREG)
-    SUBREG_BYTE (x) = value;
-  else
-    XINT (x, index) = value;
+  RTX_CODE code = GET_CODE (x);
+  const char *format_ptr = GET_RTX_FORMAT (code);
+
+  switch (format_ptr[index])
+    {
+    case 'i':
+    case 'n':
+      XINT (x, index) = value;
+      break;
+    case 'w':
+      XWINT (x, index) = value;
+      break;
+    case 'p':
+      gcc_assert (code == SUBREG);
+      SUBREG_BYTE (x) = value;
+      break;
+    default:
+      gcc_unreachable ();
+    }
 }
 
 static const char *
@@ -279,7 +351,7 @@ get_int_token (int value)
    applied.  If such attribute has already been added, then no the
    routine has no effect.  */
 static void
-apply_subst_iterator (rtx rt, unsigned int, int value)
+apply_subst_iterator (rtx rt, unsigned int, HOST_WIDE_INT value)
 {
   rtx new_attr;
   rtvec attrs_vec, new_attrs_vec;
@@ -1003,44 +1075,6 @@ initialize_iterators (void)
     }
 }
 \f
-/* Provide a version of a function to read a long long if the system does
-   not provide one.  */
-#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !HAVE_DECL_ATOLL && !defined(HAVE_ATOQ)
-HOST_WIDE_INT atoll (const char *);
-
-HOST_WIDE_INT
-atoll (const char *p)
-{
-  int neg = 0;
-  HOST_WIDE_INT tmp_wide;
-
-  while (ISSPACE (*p))
-    p++;
-  if (*p == '-')
-    neg = 1, p++;
-  else if (*p == '+')
-    p++;
-
-  tmp_wide = 0;
-  while (ISDIGIT (*p))
-    {
-      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
-      if (new_wide < tmp_wide)
-	{
-	  /* Return INT_MAX equiv on overflow.  */
-	  tmp_wide = HOST_WIDE_INT_M1U >> 1;
-	  break;
-	}
-      tmp_wide = new_wide;
-      p++;
-    }
-
-  if (neg)
-    tmp_wide = -tmp_wide;
-  return tmp_wide;
-}
-#endif
-\f
 
 #ifdef GENERATOR_FILE
 /* Process a define_conditions directive, starting with the optional
@@ -1939,32 +1973,9 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
       }
       break;
 
-    case 'w':
-      {
-	HOST_WIDE_INT tmp_wide;
-	read_name (&name);
-	validate_const_int (name.string);
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-	tmp_wide = atoi (name.string);
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-	tmp_wide = atol (name.string);
-#else
-	/* Prefer atoll over atoq, since the former is in the ISO C99 standard.
-	   But prefer not to use our hand-rolled function above either.  */
-#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
-	tmp_wide = atoll (name.string);
-#else
-	tmp_wide = atoq (name.string);
-#endif
-#endif
-#endif
-	XWINT (return_rtx, idx) = tmp_wide;
-      }
-      break;
-
     case 'i':
     case 'n':
+    case 'w':
     case 'p':
       {
 	/* Can be an iterator or an integer constant.  */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (6 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-21  4:25   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches Maciej W. Rozycki
                   ` (26 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

VAX has interlocked branch instructions used for atomic operations and
we want to have them wrapped in UNSPEC_VOLATILE so as not to have code
carried across.  This however breaks with jump optimization and leads
to an ICE in the build of libbacktrace like:

.../libbacktrace/mmap.c:190:1: internal compiler error: in fixup_reorder_chain, at cfgrtl.c:3934
  190 | }
      | ^
0x1087d46b fixup_reorder_chain
	.../gcc/cfgrtl.c:3934
0x1087f29f cfg_layout_finalize()
	.../gcc/cfgrtl.c:4447
0x1087c74f execute
	.../gcc/cfgrtl.c:3662

on RTL like:

(jump_insn 18 17 150 4 (unspec_volatile [
            (set (pc)
                (if_then_else (eq (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 1 [0x1]))
                    (label_ref 20)
                    (pc)))
            (set (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
                    (const_int 1 [0x1])
                    (const_int 0 [0]))
                (const_int 1 [0x1]))
        ] 101) ".../libbacktrace/mmap.c":135:14 158 {jbbssisi}
     (nil)
 -> 20)

when those branches are enabled with a follow-up change.  Also showing
with:

FAIL: gcc.dg/pr61756.c (internal compiler error)

Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
branches from being removed as they won't be accepted by `onlyjump_p',
we just need to let them through.

	gcc/
	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
	UNSPEC_VOLATILE.
	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
---
 gcc/jump.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/gcc/jump.c b/gcc/jump.c
index 34a8f209e20..f4c735540f0 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -850,9 +850,17 @@ pc_set (const rtx_insn *insn)
   pat = PATTERN (insn);
 
   /* The set is allowed to appear either as the insn pattern or
-     the first set in a PARALLEL.  */
-  if (GET_CODE (pat) == PARALLEL)
-    pat = XVECEXP (pat, 0, 0);
+     the first set in a PARALLEL, UNSPEC or UNSPEC_VOLATILE.  */
+  switch (GET_CODE (pat))
+    {
+    case PARALLEL:
+    case UNSPEC:
+    case UNSPEC_VOLATILE:
+      pat = XVECEXP (pat, 0, 0);
+      break;
+    default:
+      break;
+    }
   if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
     return pat;
 
@@ -860,7 +868,7 @@ pc_set (const rtx_insn *insn)
 }
 
 /* Return true when insn is an unconditional direct jump,
-   possibly bundled inside a PARALLEL.  */
+   possibly bundled inside a PARALLEL, UNSPEC or UNSPEC_VOLATILE.  */
 
 int
 any_uncondjump_p (const rtx_insn *insn)
@@ -876,9 +884,9 @@ any_uncondjump_p (const rtx_insn *insn)
 }
 
 /* Return true when insn is a conditional jump.  This function works for
-   instructions containing PC sets in PARALLELs.  The instruction may have
-   various other effects so before removing the jump you must verify
-   onlyjump_p.
+   instructions containing PC sets in PARALLELs, UNSPECs or UNSPEC_VOLATILEs.
+   The instruction may have various other effects so before removing the jump
+   you must verify onlyjump_p.
 
    Note that unlike condjump_p it returns false for unconditional jumps.  */
 
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (7 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 23:20   ` Jeff Law
  2020-11-20  3:34 ` [PATCH 10/31] VAX: Use an int " Maciej W. Rozycki
                   ` (25 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Regardless of the machine mode all the interlocked branches of the same
kind, one of the two provided by the ISA, use the same RTL patterns and
machine instructions, except for the memory operand's constraint.

Remove code duplication then and make use of a mode iterator combined
with an attribute to expand the same insn patterns with the constraint
suitably substituted from a single template.  No functional change.

	gcc/
	* config/vax/builtins.md (bb_mem): New mode attribute.
	(jbbssiqi, jbbssihi, jbbssisi): Fold insns into...
	(jbbssi<mode>): ... this.
	(jbbcciqi, jbbccihi, jbbccisi): Likewise...
	(jbbcci<mode>): ... this.
---
 gcc/config/vax/builtins.md | 96 ++++++++--------------------------------------
 1 file changed, 15 insertions(+), 81 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index 6bce7a85add..473b44f489f 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -24,6 +24,8 @@ (define_constants
   ]
 )
 
+(define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
+
 (define_expand "ffssi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
@@ -73,58 +75,24 @@ (define_expand "sync_lock_test_and_set<mode>"
   DONE;
 }")
 
-(define_insn "jbbssiqi"
-  [(parallel
-    [(set (pc)
-	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:QI 0 "memory_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")
-			   (const_int 1)
-			   (match_dup 1))
-	  (const_int 1))])]
-  ""
-  "jbssi %1,%0,%l2")
-
-(define_insn "jbbssihi"
+(define_insn "jbbssi<mode>"
   [(parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:HI 0 "memory_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")
-			   (const_int 1)
-			   (match_dup 1))
-	  (const_int 1))])]
-  ""
-  "jbssi %1,%0,%l2")
-
-(define_insn "jbbssisi"
-  [(parallel
-    [(set (pc)
-	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q")
-				 (const_int 1)
-				 (match_operand:SI 1 "general_operand" "nrm"))
-		(const_int 0))
+	    (eq (zero_extract:SI
+		  (match_operand:VAXint 0 "memory_operand" "<bb_mem>")
+		  (const_int 1)
+		  (match_operand:SI 1 "general_operand" "nrmT"))
+		(const_int 1))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
-     (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0")
+     (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
 	  (const_int 1))])]
   ""
   "jbssi %1,%0,%l2")
 
-
 (define_expand "sync_lock_release<mode>"
   [(set (match_operand:VAXint 0 "memory_operand" "+m")
 	(unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n")
@@ -145,54 +113,20 @@ (define_expand "sync_lock_release<mode>"
   DONE;
 }")
 
-(define_insn "jbbcciqi"
-  [(parallel
-    [(set (pc)
-	  (if_then_else
-	    (eq (zero_extract:SI (match_operand:QI 0 "memory_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")
-			   (const_int 1)
-			   (match_dup 1))
-	  (const_int 0))])]
-  ""
-  "jbcci %1,%0,%l2")
-
-(define_insn "jbbccihi"
+(define_insn "jbbcci<mode>"
   [(parallel
     [(set (pc)
 	  (if_then_else
-	    (eq (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q")
-				 (const_int 1)
-				 (match_operand:SI 1 "general_operand" "nrm"))
+	    (eq (zero_extract:SI
+		  (match_operand:VAXint 0 "memory_operand" "<bb_mem>")
+		  (const_int 1)
+		  (match_operand:SI 1 "general_operand" "nrmT"))
 		(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:VAXint 3 "memory_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
 	  (const_int 0))])]
   ""
   "jbcci %1,%0,%l2")
-
-(define_insn "jbbccisi"
-  [(parallel
-    [(set (pc)
-	  (if_then_else
-	    (eq (zero_extract:SI (match_operand:SI 0 "memory_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")
-			   (const_int 1)
-			   (match_dup 1))
-	  (const_int 0))])]
-  ""
-  "jbcci %1,%0,%l2")
-
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 10/31] VAX: Use an int iterator to produce individual interlocked branches
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (8 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches Maciej W. Rozycki
@ 2020-11-20  3:34 ` Maciej W. Rozycki
  2020-11-20 23:20   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins Maciej W. Rozycki
                   ` (24 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

With mode-specific interlocked branch insns already folded into iterated
templates now fold the two templates into one too, observing that the
only difference between them is the value of the bit branched on, which
is of course reflected both in the RTL expression and the instruction
produced.  Use an int iterator to iterate over the bit value, making use
of the newly-added wide integer support, and substituting patterns as
necessary to produce equivalent individual insns.  No functional change.

	gcc/
	* config/vax/builtins.md (bit): New int iterator.
	(ccss): New int attribute.
	(jbbssi<mode>, jbbcci<mode>): Fold insns into...
	(jbb<ccss>i<mode>): ... this.
---
 gcc/config/vax/builtins.md | 29 +++++++----------------------
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index 473b44f489f..8bbcd603d13 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -26,6 +26,9 @@ (define_constants
 
 (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
 
+(define_int_iterator bit [0 1])
+(define_int_attr ccss [(0 "cc") (1 "ss")])
+
 (define_expand "ffssi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
@@ -75,24 +78,6 @@ (define_expand "sync_lock_test_and_set<mode>"
   DONE;
 }")
 
-(define_insn "jbbssi<mode>"
-  [(parallel
-    [(set (pc)
-	  (if_then_else
-	    (eq (zero_extract:SI
-		  (match_operand:VAXint 0 "memory_operand" "<bb_mem>")
-		  (const_int 1)
-		  (match_operand:SI 1 "general_operand" "nrmT"))
-		(const_int 1))
-	    (label_ref (match_operand 2 "" ""))
-	    (pc)))
-     (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0")
-			   (const_int 1)
-			   (match_dup 1))
-	  (const_int 1))])]
-  ""
-  "jbssi %1,%0,%l2")
-
 (define_expand "sync_lock_release<mode>"
   [(set (match_operand:VAXint 0 "memory_operand" "+m")
 	(unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n")
@@ -113,7 +98,7 @@ (define_expand "sync_lock_release<mode>"
   DONE;
 }")
 
-(define_insn "jbbcci<mode>"
+(define_insn "jbb<ccss>i<mode>"
   [(parallel
     [(set (pc)
 	  (if_then_else
@@ -121,12 +106,12 @@ (define_insn "jbbcci<mode>"
 		  (match_operand:VAXint 0 "memory_operand" "<bb_mem>")
 		  (const_int 1)
 		  (match_operand:SI 1 "general_operand" "nrmT"))
-		(const_int 0))
+		(const_int bit))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
      (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
-	  (const_int 0))])]
+	  (const_int bit))])]
   ""
-  "jbcci %1,%0,%l2")
+  "jb<ccss>i %1,%0,%l2")
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (9 preceding siblings ...)
  2020-11-20  3:34 ` [PATCH 10/31] VAX: Use an int " Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-21  4:26   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional Maciej W. Rozycki
                   ` (23 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Remove an ICE like:

during RTL pass: expand
.../libatomic/tas_n.c: In function 'libat_test_and_set_1':
.../libatomic/tas_n.c:39:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1298
   39 | }
      | ^
0x108a09ff patch_jump_insn
	.../gcc/cfgrtl.c:1298
0x108a0b07 redirect_branch_edge
	.../gcc/cfgrtl.c:1325
0x108a124b rtl_redirect_edge_and_branch
	.../gcc/cfgrtl.c:1458
0x1087f6d3 redirect_edge_and_branch(edge_def*, basic_block_def*)
	.../gcc/cfghooks.c:373
0x11d6264b try_forward_edges
	.../gcc/cfgcleanup.c:562
0x11d6b0eb try_optimize_cfg
	.../gcc/cfgcleanup.c:2960
0x11d6ba4f cleanup_cfg(int)
	.../gcc/cfgcleanup.c:3174
0x10870b3f execute
	.../gcc/cfgexpand.c:6763

triggered with an RTL pattern like:

(jump_insn 8 7 20 2 (parallel [
            (set (pc)
                (if_then_else (ne (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 0 [0]))
                    (label_ref 10)
                    (pc)))
            (set (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
                    (const_int 1 [0x1])
                    (const_int 0 [0]))
                (const_int 1 [0x1]))
        ]) ".../libatomic/tas_n.c":38:12 -1
     (nil)
 -> 10)

caused by a volatile memory reference used that is not accepted by the
`memory_operand' predicate of the `jbbssiqi' insn explicitly referred
from the `sync_lock_test_and_setqi' expander.  Also seen with:

FAIL: gcc.dg/pr61756.c (internal compiler error)

Define a new `any_memory_operand' predicate accepting both ordinary and
volatile memory references and use it with the `jbb<ccss>i<mode>' insn,
so as to address the ICE.

Also remove useless operations from the `sync_lock_test_and_set<mode>'
and `sync_lock_release<mode>' expanders as those always either complete
or fail and therefore never fall through to using their template other
than to match operands.  Wrap `jbb<ccss>i<mode>' into `unspec_volatile'
instead so that the jump does not get removed or reordered.  Share one
index to avoid a complication around the iterators since the index is
nowhere referred to anyway and the pattern required pulled by its name.

Test cases will be added separately.

	gcc/
	* config/vax/predicates.md (volatile_mem_operand)
	(any_memory_operand): New predicates.
	* config/vax/builtins.md (VUNSPEC_UNLOCK): Remove constant.
	(sync_lock_test_and_set<mode>): Remove `set' and `unspec'
	operations, match operands only.  Reformat.
	(sync_lock_release<mode>): Likewise.  Remove cruft.
	(jbb<ccss>i<mode>): Wrap into `unspec_volatile', use
	`any_memory_operand' predicate.
---
 gcc/config/vax/builtins.md   | 36 +++++++++++++++++-------------------
 gcc/config/vax/predicates.md | 16 ++++++++++++++++
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index 8bbcd603d13..7e27854a8b0 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -19,8 +19,7 @@
 
 (define_constants
   [
-    (VUNSPEC_LOCK 100)		; sync lock and test
-    (VUNSPEC_UNLOCK 101)	; sync lock release
+    (VUNSPEC_LOCK 100)		; sync lock operations
   ]
 )
 
@@ -58,10 +57,9 @@ (define_insn "ffssi2_internal"
   "ffs $0,$32,%1,%0")
 
 (define_expand "sync_lock_test_and_set<mode>"
-  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=&g")
-	(unspec:VAXint [(match_operand:VAXint 1 "memory_operand" "+m")
-		    (match_operand:VAXint 2 "const_int_operand" "n")
-		   ] VUNSPEC_LOCK))]
+  [(match_operand:VAXint 0 "nonimmediate_operand" "=&g")
+   (match_operand:VAXint 1 "memory_operand" "+m")
+   (match_operand:VAXint 2 "const_int_operand" "n")]
   ""
   "
 {
@@ -72,46 +70,46 @@ (define_expand "sync_lock_test_and_set<mode>"
 
   label = gen_label_rtx ();
   emit_move_insn (operands[0], const1_rtx);
-  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label, operands[1]));
+  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label,
+				    operands[1]));
   emit_move_insn (operands[0], const0_rtx);
   emit_label (label);
   DONE;
 }")
 
 (define_expand "sync_lock_release<mode>"
-  [(set (match_operand:VAXint 0 "memory_operand" "+m")
-	(unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n")
-		   ] VUNSPEC_UNLOCK))]
+  [(match_operand:VAXint 0 "memory_operand" "+m")
+   (match_operand:VAXint 1 "const_int_operand" "n")]
   ""
   "
 {
   rtx label;
+
   if (operands[1] != const0_rtx)
     FAIL;
-#if 1
+
   label = gen_label_rtx ();
-  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label, operands[0]));
+  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label,
+				    operands[0]));
   emit_label (label);
-#else
-  emit_move_insn (operands[0], const0_rtx);
-#endif
   DONE;
 }")
 
 (define_insn "jbb<ccss>i<mode>"
-  [(parallel
+  [(unspec_volatile
     [(set (pc)
 	  (if_then_else
 	    (eq (zero_extract:SI
-		  (match_operand:VAXint 0 "memory_operand" "<bb_mem>")
+		  (match_operand:VAXint 0 "any_memory_operand" "<bb_mem>")
 		  (const_int 1)
 		  (match_operand:SI 1 "general_operand" "nrmT"))
 		(const_int bit))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
-     (set (zero_extract:SI (match_operand:VAXint 3 "memory_operand" "+0")
+     (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
-	  (const_int bit))])]
+	  (const_int bit))]
+    VUNSPEC_LOCK)]
   ""
   "jb<ccss>i %1,%0,%l2")
diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md
index 93e91e499a6..7c97b366604 100644
--- a/gcc/config/vax/predicates.md
+++ b/gcc/config/vax/predicates.md
@@ -93,3 +93,19 @@ (define_predicate "general_addsub_di_operand"
    (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 (match_code "mem")
+       (match_test "MEM_VOLATILE_P (op)")
+       (if_then_else (match_test "reload_completed")
+	 (match_operand 0 "memory_operand")
+	 (match_test "memory_address_p (mode, XEXP (op, 0))"))))
+
+;; Return 1 if the operand is a volatile or non-volatile memory operand.
+(define_predicate "any_memory_operand"
+  (ior (match_operand 0 "memory_operand")
+       (match_operand 0 "volatile_mem_operand")))
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (10 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:21   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation Maciej W. Rozycki
                   ` (22 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Test cases will follow.

	gcc/
	* config/vax/vax.md: Include `builtins.md'.
---
 gcc/config/vax/vax.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index e6b217fd0d7..66f03df1932 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -1634,3 +1634,5 @@ (define_expand "nonlocal_goto"
   emit_barrier ();
   DONE;
 })
+
+(include "builtins.md")
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (11 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:22   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release' Maciej W. Rozycki
                   ` (21 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

	gcc/testsuite/
	* gcc.target/vax/ffssi.c: New test.
---
 gcc/testsuite/gcc.target/vax/ffssi.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/vax/ffssi.c

diff --git a/gcc/testsuite/gcc.target/vax/ffssi.c b/gcc/testsuite/gcc.target/vax/ffssi.c
new file mode 100644
index 00000000000..3e7a3c2b301
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ffssi.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+int
+ffssi (int x)
+{
+  return __builtin_ffs (x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$32,%r1,%r0
+	jneq .L2
+	mnegl $1,%r0
+.L2:
+	incl %r0
+
+ */
+
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$32," } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release'
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (12 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:22   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 15/31] VAX: Provide the `ctz' operation Maciej W. Rozycki
                   ` (20 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Based on gcc.dg/pr61756.c.

	gcc/testsuite/
	* gcc.target/vax/bbcci.c: New test.
	* gcc.target/vax/bbssi.c: New test.
---
 gcc/testsuite/gcc.target/vax/bbcci.c | 20 ++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/bbssi.c | 20 ++++++++++++++++++++
 2 files changed, 40 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/vax/bbcci.c
 create mode 100644 gcc/testsuite/gcc.target/vax/bbssi.c

diff --git a/gcc/testsuite/gcc.target/vax/bbcci.c b/gcc/testsuite/gcc.target/vax/bbcci.c
new file mode 100644
index 00000000000..f58d3a75e7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/bbcci.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+#include <stdatomic.h>
+
+extern volatile atomic_flag guard;
+
+void
+try_atomic_flag_clear (void)
+{
+  atomic_flag_clear (&guard);
+}
+
+/* Expect assembly like:
+
+	jbcci $0,guard,.L2
+.L2:
+
+ */
+
+/* { dg-final { scan-assembler "\tjbcci \\\$0,guard," } } */
diff --git a/gcc/testsuite/gcc.target/vax/bbssi.c b/gcc/testsuite/gcc.target/vax/bbssi.c
new file mode 100644
index 00000000000..65111e9bdf2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/bbssi.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+#include <stdatomic.h>
+
+extern volatile atomic_flag guard;
+
+void
+try_atomic_flag_test_and_set (void)
+{
+  atomic_flag_test_and_set (&guard);
+}
+
+/* Expect assembly like:
+
+	jbssi $0,guard,.L1
+.L1:
+
+ */
+
+/* { dg-final { scan-assembler "\tjbssi \\\$0,guard," } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 15/31] VAX: Provide the `ctz' operation
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (13 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release' Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:23   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations Maciej W. Rozycki
                   ` (19 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Our `ffssi2_internal' pattern and the machine FFS instruction, which
technically is a bitfield operation, match the `ctz' operation exactly,
with the result produced for the bitfield source operand of zero equal
to its width as specified with another machine instruction operand, not
directly expressed in RTL and currently hardcoded in the assembly code
produced.  In our terms this is the bit size of the machine mode used,
and although it's SImode now let's be flexible for an upcoming change.

The operation also sets the Z condition code according to the value of
the source operand.

	gcc/
	* config/vax/builtins.md (ffssi2_internal): Rename insn to...
	(ctzsi2): ... this.  Update the RTL operation.
	(ffssi2): Update accordingly.
	* gcc/config/vax/vax.c (vax_notice_update_cc): Handle CTZ.
	* gcc/config/vax/vax.h (CTZ_DEFINED_VALUE_AT_ZERO): New macro.

	gcc/testsuite/
	* gcc.target/vax/ctzsi.c: New test.
---
 gcc/config/vax/builtins.md           |  6 +++---
 gcc/config/vax/vax.c                 |  3 +++
 gcc/config/vax/vax.h                 |  4 ++++
 gcc/testsuite/gcc.target/vax/ctzsi.c | 15 +++++++++++++++
 4 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/vax/ctzsi.c

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index 7e27854a8b0..e8cefe70d25 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -39,7 +39,7 @@ (define_expand "ffssi2"
   rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
 
-  emit_insn (gen_ffssi2_internal (operands[0], operands[1]));
+  emit_insn (gen_ctzsi2 (operands[0], operands[1]));
   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
   emit_insn (gen_negsi2 (operands[0], const1_rtx));
   emit_label (label);
@@ -47,9 +47,9 @@ (define_expand "ffssi2"
   DONE;
 }")
 
-(define_insn "ffssi2_internal"
+(define_insn "ctzsi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
-	(ffs:SI (match_operand:SI 1 "general_operand" "nrQT")))
+	(ctz:SI (match_operand:SI 1 "general_operand" "nrQT")))
    (set (cc0)
 	(compare (match_dup 1)
 		 (const_int 0)))]
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index b6c2210ca6b..69a05b33e95 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -1135,6 +1135,9 @@ vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
 	    case REG:
 	      cc_status.flags = CC_NO_OVERFLOW;
 	      break;
+	    case CTZ:
+	      cc_status.flags = CC_NOT_NEGATIVE;
+	      break;
 	    default:
 	      break;
 	    }
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index 146b0a6e2b2..43182ff1d88 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -683,3 +683,7 @@ VAX operand formatting codes:
    by the proper FDE definition.  */
 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM)
 
+/* Upon failure to find the bit the FFS hardware instruction returns
+   the position of the bit immediately following the field specified.  */
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)	\
+  ((VALUE) = GET_MODE_BITSIZE (MODE), 2)
diff --git a/gcc/testsuite/gcc.target/vax/ctzsi.c b/gcc/testsuite/gcc.target/vax/ctzsi.c
new file mode 100644
index 00000000000..8be42712c77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ctzsi.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+int
+ctzsi (unsigned int x)
+{
+  return __builtin_ctz (x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$32,4(%ap),%r0
+
+ */
+
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$32," } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (14 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 15/31] VAX: Provide the `ctz' operation Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:24   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations Maciej W. Rozycki
                   ` (18 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The FFS machine instruction provides for arbitrary input bitfield widths
so take advantage of this and convert `ffssi2' and `ctzsi2' to templates
for all the three of QI, HI, SI machine modes.

Test cases will be added separately.

	gcc/
	* config/vax/builtins.md (width): New mode attribute.
	(ffssi2): Rework expander into...
	(ffs<mode>2): ... this.
	(ctzsi2): Rework insn into...
	(ctz<mode>2): ... this.
---
 gcc/config/vax/builtins.md | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index e8cefe70d25..b7ed9762c23 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -23,14 +23,15 @@ (define_constants
   ]
 )
 
+(define_mode_attr width [(QI "8") (HI "16") (SI "32")])
 (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
 
 (define_int_iterator bit [0 1])
 (define_int_attr ccss [(0 "cc") (1 "ss")])
 
-(define_expand "ffssi2"
+(define_expand "ffs<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
-	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
+	(ffs:SI (match_operand:VAXint 1 "general_operand" "")))]
   ""
   "
 {
@@ -39,22 +40,22 @@ (define_expand "ffssi2"
   rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
 
-  emit_insn (gen_ctzsi2 (operands[0], operands[1]));
+  emit_insn (gen_ctz<mode>2 (operands[0], operands[1]));
   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
-  emit_insn (gen_negsi2 (operands[0], const1_rtx));
+  emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
   emit_label (label);
-  emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
+  emit_insn (gen_add<mode>3 (operands[0], operands[0], const1_rtx));
   DONE;
 }")
 
-(define_insn "ctzsi2"
+(define_insn "ctz<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
-	(ctz:SI (match_operand:SI 1 "general_operand" "nrQT")))
+	(ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
    (set (cc0)
 	(compare (match_dup 1)
 		 (const_int 0)))]
   ""
-  "ffs $0,$32,%1,%0")
+  "ffs $0,$<width>,%1,%0")
 
 (define_expand "sync_lock_test_and_set<mode>"
   [(match_operand:VAXint 0 "nonimmediate_operand" "=&g")
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (15 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:24   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction Maciej W. Rozycki
                   ` (17 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The middle end does not refer to `ctzqi2'/`ctzhi2' or `ffsqi2'/`ffshi2'
patterns by name where `__builtin_ctz' or `__builtin_ffs' respectively
is invoked for an argument of the QImode or HImode type, and instead it
extends the data type before passing it to `ctzsi2' or `ffssi2'.

Avoid the redundant operation and use a peephole2 to convert it to the
right RTL expression that will collapse the two operations into a single
machine instruction instead unless we need the extended intermediate
result for another purpose.

	gcc/
	* config/vax/builtins.md: Add a peephole2 for QImode and HImode
	`ctz' operations.
	(any_extend): New code iterator.

	gcc/testsuite/
	* gcc.target/vax/ctzhi.c: New test.
	* gcc.target/vax/ctzqi.c: New test.
	* gcc.target/vax/ffshi.c: New test.
	* gcc.target/vax/ffsqi.c: New test.
---
 gcc/config/vax/builtins.md           | 22 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/ctzhi.c | 20 ++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/ctzqi.c | 20 ++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/ffshi.c | 24 ++++++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/ffsqi.c | 24 ++++++++++++++++++++++++
 5 files changed, 110 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/vax/ctzhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/ctzqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/ffshi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/ffsqi.c

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index b7ed9762c23..e96ac3f52ab 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -29,6 +29,8 @@ (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
 (define_int_iterator bit [0 1])
 (define_int_attr ccss [(0 "cc") (1 "ss")])
 
+(define_code_iterator any_extend [sign_extend zero_extend])
+
 (define_expand "ffs<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 	(ffs:SI (match_operand:VAXint 1 "general_operand" "")))]
@@ -57,6 +59,26 @@ (define_insn "ctz<mode>2"
   ""
   "ffs $0,$<width>,%1,%0")
 
+;; Our FFS hardware instruction supports any field width,
+;; so handle narrower inputs directly as well.
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand")
+        (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+   (parallel
+     [(set (match_operand:SI 2 "nonimmediate_operand")
+	   (ctz:SI (match_dup 0)))
+      (set (cc0)
+	   (compare (match_dup 2)
+		    (const_int 0)))])]
+  "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])"
+  [(parallel
+     [(set (match_dup 2)
+	   (ctz:SI (match_dup 1)))
+      (set (cc0)
+	   (compare (match_dup 1)
+		    (const_int 0)))])]
+  "")
+
 (define_expand "sync_lock_test_and_set<mode>"
   [(match_operand:VAXint 0 "nonimmediate_operand" "=&g")
    (match_operand:VAXint 1 "memory_operand" "+m")
diff --git a/gcc/testsuite/gcc.target/vax/ctzhi.c b/gcc/testsuite/gcc.target/vax/ctzhi.c
new file mode 100644
index 00000000000..fcc9f06f7d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ctzhi.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (HI))) int_t;
+
+int
+ctzhi (int_t *x)
+{
+  return __builtin_ctz (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$16,*4(%ap),%r0
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$16," } } */
diff --git a/gcc/testsuite/gcc.target/vax/ctzqi.c b/gcc/testsuite/gcc.target/vax/ctzqi.c
new file mode 100644
index 00000000000..067334b09e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ctzqi.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (QI))) int_t;
+
+int
+ctzqi (int_t *x)
+{
+  return __builtin_ctz (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$8,*4(%ap),%r0
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$8," } } */
diff --git a/gcc/testsuite/gcc.target/vax/ffshi.c b/gcc/testsuite/gcc.target/vax/ffshi.c
new file mode 100644
index 00000000000..db592fb5724
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ffshi.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+int
+ffshi (int_t *x)
+{
+  return __builtin_ffs (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$16,*4(%ap),%r0
+	jneq .L2
+	mnegl $1,%r0
+.L2:
+	incl %r0
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$16," } } */
diff --git a/gcc/testsuite/gcc.target/vax/ffsqi.c b/gcc/testsuite/gcc.target/vax/ffsqi.c
new file mode 100644
index 00000000000..ebcd9460754
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/ffsqi.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+int
+ffsqi (int_t *x)
+{
+  return __builtin_ffs (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$8,*4(%ap),%r0
+	jneq .L2
+	mnegl $1,%r0
+.L2:
+	incl %r0
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler "\tffs \\\$0,\\\$8," } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (16 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:25   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 19/31] VAX: Add the `movmemhi' instruction Maciej W. Rozycki
                   ` (16 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

	gcc/testsuite/
	* gcc.target/vax/cpymem.c: New test.
---
 gcc/testsuite/gcc.target/vax/cpymem.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/vax/cpymem.c

diff --git a/gcc/testsuite/gcc.target/vax/cpymem.c b/gcc/testsuite/gcc.target/vax/cpymem.c
new file mode 100644
index 00000000000..91805a1a5eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cpymem.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+#include <stddef.h>
+
+void *
+memcpy8 (void *to, const void *from, size_t size)
+{
+  unsigned char s8 = size;
+  return __builtin_memcpy (to, from, s8);
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r6
+	movzbl 12(%ap),%r7
+	movl 8(%ap),%r8
+	movc3 %r7,(%r8),(%r6)
+	movl %r6,%r0
+
+ */
+
+/* { dg-final { scan-assembler "\tmovc3 " } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 19/31] VAX: Add the `movmemhi' instruction
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (17 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-20 23:25   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns Maciej W. Rozycki
                   ` (15 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The MOVC3 machine instruction has `memmove' semantics[1]:

"The operation of the instruction is such that overlap of the source and
destination strings does not affect the result."

so use it to provide the `movmemhi' instruction as well.

References:

[1] DEC STD 032-0 "VAX Architecture Standard", Digital Equipment
    Corporation, A-DS-EL-00032-00-0 Rev J, December 15, 1989, Section
    3.10 "Character-String Instructions", p. 3-162

	gcc/
	* config/vax/vax.md (cpymemhi1): Rename insn to...
	(movmemhi1): ... this.
	(cpymemhi): Update accordingly.  Remove constraints.
	(movmemhi): New expander.

	gcc/testsuite/
	* gcc.target/vax/movmem.c: New test.
---
 gcc/config/vax/vax.md                 | 24 ++++++++++++++++++------
 gcc/testsuite/gcc.target/vax/movmem.c | 23 +++++++++++++++++++++++
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/vax/movmem.c

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 66f03df1932..f8e1c2eb02b 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -206,16 +206,28 @@ (define_insn "movstrictqi"
 }")
 
 ;; This is here to accept 4 arguments and pass the first 3 along
-;; to the cpymemhi1 pattern that really does the work.
+;; to the movmemhi1 pattern that really does the work.
 (define_expand "cpymemhi"
-  [(set (match_operand:BLK 0 "general_operand" "=g")
-	(match_operand:BLK 1 "general_operand" "g"))
-   (use (match_operand:HI 2 "general_operand" "g"))
+  [(set (match_operand:BLK 0 "memory_operand" "")
+	(match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:HI 2 "general_operand" ""))
+   (match_operand 3 "" "")]
+  ""
+  "
+{
+  emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_expand "movmemhi"
+  [(set (match_operand:BLK 0 "memory_operand" "")
+	(match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:HI 2 "general_operand" ""))
    (match_operand 3 "" "")]
   ""
   "
 {
-  emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2]));
+  emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
   DONE;
 }")
 
@@ -224,7 +236,7 @@ (define_expand "cpymemhi"
 ;; that anything generated as this insn will be recognized as one
 ;; and that it won't successfully combine with anything.
 
-(define_insn "cpymemhi1"
+(define_insn "movmemhi1"
   [(set (match_operand:BLK 0 "memory_operand" "=o")
 	(match_operand:BLK 1 "memory_operand" "o"))
    (use (match_operand:HI 2 "general_operand" "g"))
diff --git a/gcc/testsuite/gcc.target/vax/movmem.c b/gcc/testsuite/gcc.target/vax/movmem.c
new file mode 100644
index 00000000000..b907d8a376d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/movmem.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+#include <stddef.h>
+
+void *
+memmove8 (void *to, const void *from, size_t size)
+{
+  unsigned char s8 = size;
+  return __builtin_memmove (to, from, s8);
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r6
+	movzbl 12(%ap),%r7
+	movl 8(%ap),%r8
+	movc3 %r7,(%r8),(%r6)
+	movl %r6,%r0
+
+ */
+
+/* { dg-final { scan-assembler "\tmovc3 " } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (18 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 19/31] VAX: Add the `movmemhi' instruction Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-21 17:01   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns Maciej W. Rozycki
                   ` (14 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

It makes no sense for insn operand predicates, as long as they accept a
register operand, to be more restrictive than the set of the associated
constraints, because expand will choose the insn based on the relevant
operand being a pseudo register then and reload keep it happily as a
memory reference if a constraint permits it.  So the restriction posed
by such a predicate will be happily ignored, and moreover if a splitter
is added, such as required for MODE_CC support, the new instructions
will reject the original operands supplied, causing an ICE.  An actual
example will be given with a subsequent change.

Remove such inconsistencies we have with the EXTV/EXTZV/INSV insns then,
observing that a bitfield located in memory is byte-addressed by the
respective machine instructions and therefore SImode may only be used
with a register or an offsettable memory operand (i.e. not an indexed,
pre-decremented, or post-incremented one), which has already been taken
into account with the constraints currently used, except for `*insv_2'.
The QI machine mode may be used for the bitfield location with any kind
of memory operand, but we got the constraint wrong, although harmlessly
in reality, with `*insv'.  Fix that for consistency though.

Also give the insns names, for easier reference here and elsewhere.

	gcc/
	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
	(*extv_aligned, *extv_non_const, *extzv_non_const): Name insns.
	Fix location predicate.
	(*extzv): Name insn.
	(*insv): Likewise.  Fix location constraint.
	(*insv_2): Likewise, and the predicate.
---
 gcc/config/vax/vax.md | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index f8e1c2eb02b..de90848a600 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -757,8 +757,8 @@ (define_insn ""
 ;; These handle aligned 8-bit and 16-bit fields,
 ;; which can usually be done with move instructions.
 
-(define_insn ""
-  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
+(define_insn "*insv_aligned"
+  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
 			 (match_operand:QI 1 "const_int_operand" "n")
 			 (match_operand:SI 2 "const_int_operand" "n"))
 	(match_operand:SI 3 "general_operand" "g"))]
@@ -786,9 +786,9 @@ (define_insn ""
   return \"movw %3,%0\";
 }")
 
-(define_insn ""
+(define_insn "*extzv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
-	(zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
+	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "const_int_operand" "n")
 			 (match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
@@ -814,9 +814,9 @@ (define_insn ""
   return \"movzwl %1,%0\";
 }")
 
-(define_insn ""
+(define_insn "*extv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
+	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "const_int_operand" "n")
 			 (match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
@@ -842,7 +842,7 @@ (define_insn ""
   return \"cvtwl %1,%0\";
 }")
 \f
-;; Register-only SImode cases of bit-field insns.
+;; Register and non-offsettable-memory SImode cases of bit-field insns.
 
 (define_insn ""
   [(set (cc0)
@@ -869,9 +869,9 @@ (define_insn ""
 ;; by a bicl or sign extension.  Because we might end up choosing ext[z]v
 ;; anyway, we can't allow immediate values for the primary source operand.
 
-(define_insn ""
+(define_insn "*extv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
+	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
@@ -886,9 +886,9 @@ (define_insn ""
   return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
 }")
 
-(define_insn ""
+(define_insn "*extzv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-	(zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
+	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
@@ -962,7 +962,7 @@ (define_expand "extzv"
   ""
   "")
 
-(define_insn ""
+(define_insn "*extzv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
 			 (match_operand:QI 2 "general_operand" "g")
@@ -1015,8 +1015,8 @@ (define_expand "insv"
   ""
   "")
 
-(define_insn ""
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
+(define_insn "*insv"
+  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
 			 (match_operand:QI 1 "general_operand" "g")
 			 (match_operand:SI 2 "general_operand" "nrmT"))
 	(match_operand:SI 3 "general_operand" "nrmT"))]
@@ -1046,8 +1046,8 @@ (define_insn ""
   return \"insv %3,%2,%1,%0\";
 }")
 
-(define_insn ""
-  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+(define_insn "*insv_2"
+  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
 			 (match_operand:QI 1 "general_operand" "g")
 			 (match_operand:SI 2 "general_operand" "nrmT"))
 	(match_operand:SI 3 "general_operand" "nrmT"))]
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (19 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-21 17:25   ` Jeff Law
  2020-11-20  3:35 ` [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns Maciej W. Rozycki
                   ` (13 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The INSV machine instruction is the only computational operation in the
VAX ISA that keeps condition codes intact.  In preparation to MODE_CC
transition keep patterns apart then that make or do not make use of said
instruction.  For consistency update EXTV and EXTZV instruction uses
accordingly.  In expand SUBREGs will be presented as operands, so handle
that possibility in the insn condition.

This actually yields better code by avoiding EXTV/EXTZV instructions in
pseudo-aligned register cases previously resorting to those instructions:

@@ -42,7 +42,7 @@ ins8:
 	subl2 $4,%sp	# 21	[c=32]  addsi3
 	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
 	movl 8(%ap),%r1	# 17	[c=16]  movsi_2
-	insv %r1,$8,$8,%r0	# 9	[c=4]  *insv_aligned
+	insv %r1,$8,$8,%r0	# 9	[c=4]  *insv_2
 	ret		# 25	[c=0]  return
 	.size	ins8, .-ins8
 	.align 1
@@ -60,12 +60,12 @@ ext8:
 .globl extz8
 	.type	extz8, @function
 extz8:
-	.word 0	# 19	[c=0]  procedure_entry_mask
-	subl2 $4,%sp	# 20	[c=32]  addsi3
+	.word 0	# 18	[c=0]  procedure_entry_mask
+	subl2 $4,%sp	# 19	[c=32]  addsi3
 	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
-	extzv $8,$8,%r0,%r1	# 13	[c=60]  *extzv_aligned
-	movl %r1,%r0	# 18	[c=4]  movsi_2
-	ret		# 24	[c=0]  return
+	rotl $24,%r0,%r0	# 13	[c=60]  *extzv_non_const
+	movzbl %r0,%r0
+	ret		# 23	[c=0]  return
 	.size	extz8, .-extz8
 	.align 1
 .globl ins16
@@ -75,7 +75,7 @@ ins16:
 	subl2 $4,%sp	# 21	[c=32]  addsi3
 	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
 	movl 8(%ap),%r1	# 17	[c=16]  movsi_2
-	insv %r1,$16,$16,%r0	# 9	[c=4]  *insv_aligned
+	insv %r1,$16,$16,%r0	# 9	[c=4]  *insv_2
 	ret		# 25	[c=0]  return
 	.size	ins16, .-ins16
 	.align 1
@@ -94,8 +94,9 @@ ext16:
 extz16:
 	.word 0	# 18	[c=0]  procedure_entry_mask
 	subl2 $4,%sp	# 19	[c=32]  addsi3
-	movl 4(%ap),%r1	# 2	[c=16]  movsi_2
-	extzv $16,$16,%r1,%r0	# 7	[c=60]  *extzv_aligned
+	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
+	rotl $16,%r0,%r0	# 7	[c=60]  *extzv_non_const
+	movzwl %r0,%r0
 	movzwl %r0,%r0	# 13	[c=4]  zero_extendhisi2
 	ret		# 23	[c=0]  return
 	.size	extz16, .-extz16

demonstrated with this program:

typedef struct
{
  int f0:1;
  int f1:7;
  int f8:8;
  int f16:16;
} bit_t;

typedef struct
{
  unsigned int f0:1;
  unsigned int f1:7;
  unsigned int f8:8;
  unsigned int f16:16;
} ubit_t;

typedef union
{
  bit_t b;
  int i;
} bit_u;

typedef union
{
  ubit_t b;
  unsigned int i;
} ubit_u;

int
ins1 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f1 = y;
  return x.i;
}

int
ext1 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f1;
}

unsigned int
extz1 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f1;
}

int
ins8 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f8 = y;
  return x.i;
}

int
ext8 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f8;
}

unsigned int
extz8 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f8;
}

int
ins16 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f16 = y;
  return x.i;
}

int
ext16 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f16;
}

unsigned int
extz16 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f16;
}

It also papers over a regression:

FAIL: gcc.dg/pr83623.c (internal compiler error)
FAIL: gcc.dg/pr83623.c (test for excess errors)

from an ICE like:

during RTL pass: final
.../gcc/testsuite/gcc.dg/pr83623.c: In function 'foo':
.../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
0x10a056e3 change_address_1
	.../gcc/emit-rtl.c:2275
0x10a0645f adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
	.../gcc/emit-rtl.c:2409
0x11cb588f output_97
	.../gcc/config/vax/vax.md:808
0x10aafb2f get_insn_template(int, rtx_insn*)
	.../gcc/final.c:2070
0x10ab2b3f final_scan_insn_1
	.../gcc/final.c:3039
0x10ab313b final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
	.../gcc/final.c:3152
0x10aaf887 final_1
	.../gcc/final.c:2020
0x10ab703b rest_of_handle_final
	.../gcc/final.c:4658
0x10ab757b execute
	.../gcc/final.c:4736
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
compiler exited with status 1
FAIL: gcc.dg/pr83623.c (internal compiler error)

triggered by an RTL instruction like:

(insn 17 14 145 (set (reg:SI 1 %r1)
        (zero_extract:SI (mem/c:SI (symbol_ref:SI ("x") <var_decl 0x7ffff7f80120 x>) [1 x+0 S4 A128])
            (const_int 16 [0x10])
            (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/pr83623.c":12:9 97 {*extzv_aligned}
     (nil))

(where the address cannot be adjusted by 2 for PIC code as requested
here as it would create an offset external symbol reference) otherwise
caused by the patterns modified here, addressed next.  This indicates
a further rework is warranted here, but at least problems at hand have
been fixed.

	gcc/
	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
	(*extv_aligned): Reject register bitfield locations that are not
	aligned to the least significant bit; update output statement
	accordingly.
---
 gcc/config/vax/vax.md | 46 +++++++++++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index de90848a600..80f09d97727 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -754,8 +754,8 @@ (define_insn ""
 \f
 ;; Special cases of bit-field insns which we should
 ;; recognize in preference to the general case.
-;; These handle aligned 8-bit and 16-bit fields,
-;; which can usually be done with move instructions.
+;; These handle aligned 8-bit and 16-bit fields
+;; that can be done with move or convert instructions.
 
 (define_insn "*insv_aligned"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
@@ -766,19 +766,19 @@ (define_insn "*insv_aligned"
    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
    && (!MEM_P (operands[0])
        || ! mode_dependent_address_p (XEXP (operands[0], 0),
-				       MEM_ADDR_SPACE (operands[0])))"
+				      MEM_ADDR_SPACE (operands[0])))
+   && (!(REG_P (operands[0])
+	 || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
+       || INTVAL (operands[2]) == 0)"
   "*
 {
-  if (REG_P (operands[0]))
-    {
-      if (INTVAL (operands[2]) != 0)
-	return \"insv %3,%2,%1,%0\";
-    }
-  else
+  if (!REG_P (operands[0]))
     operands[0]
       = adjust_address (operands[0],
 			INTVAL (operands[1]) == 8 ? QImode : HImode,
 			INTVAL (operands[2]) / 8);
+  else
+    gcc_assert (INTVAL (operands[2]) == 0);
 
   CC_STATUS_INIT;
   if (INTVAL (operands[1]) == 8)
@@ -795,19 +795,19 @@ (define_insn "*extzv_aligned"
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    && (!MEM_P (operands[1])
        || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))"
+				      MEM_ADDR_SPACE (operands[1])))
+   && (!(REG_P (operands[1])
+	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)"
   "*
 {
-  if (REG_P (operands[1]))
-    {
-      if (INTVAL (operands[3]) != 0)
-	return \"extzv %3,%2,%1,%0\";
-    }
-  else
+  if (!REG_P (operands[1]))
     operands[1]
       = adjust_address (operands[1],
 			INTVAL (operands[2]) == 8 ? QImode : HImode,
 			INTVAL (operands[3]) / 8);
+  else
+    gcc_assert (INTVAL (operands[3]) == 0);
 
   if (INTVAL (operands[2]) == 8)
     return \"movzbl %1,%0\";
@@ -823,19 +823,19 @@ (define_insn "*extv_aligned"
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    && (!MEM_P (operands[1])
        || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))"
+				      MEM_ADDR_SPACE (operands[1])))
+   && (!(REG_P (operands[1])
+	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)"
   "*
 {
-  if (REG_P (operands[1]))
-    {
-      if (INTVAL (operands[3]) != 0)
-	return \"extv %3,%2,%1,%0\";
-    }
-  else
+  if (!REG_P (operands[1]))
     operands[1]
       = adjust_address (operands[1],
 			INTVAL (operands[2]) == 8 ? QImode : HImode,
 			INTVAL (operands[3]) / 8);
+  else
+    gcc_assert (INTVAL (operands[3]) == 0);
 
   if (INTVAL (operands[2]) == 8)
     return \"cvtbl %1,%0\";
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (20 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns Maciej W. Rozycki
@ 2020-11-20  3:35 ` Maciej W. Rozycki
  2020-11-21 17:03   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations Maciej W. Rozycki
                   ` (12 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:35 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

With the `*insv_aligned', `*extzv_aligned' and `*extv_aligned' insns we
are going to adjust the bitfield location if it is in memory, so only
allow such location addresses that can be offset, excluding external
symbol references in the PIC mode in particular.

This fixes an ICE like:

during RTL pass: final
In file included from .../gcc/testsuite/gcc.dg/torture/vshuf-v16qi.c:11:
.../gcc/testsuite/gcc.dg/torture/vshuf-main.inc: In function 'test_13':
.../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:27:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
.../gcc/testsuite/gcc.dg/torture/vshuf-16.inc:16:1: note: in expansion of macro 'T'
.../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:28:1: note: in expansion of macro 'TESTS'
0x10a34b33 change_address_1
	.../gcc/emit-rtl.c:2275
0x10a358af adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
	.../gcc/emit-rtl.c:2409
0x11d2505f output_97
	.../gcc/config/vax/vax.md:806
0x10adec4b get_insn_template(int, rtx_insn*)
	.../gcc/final.c:2070
0x10ae1c5b final_scan_insn_1
	.../gcc/final.c:3039
0x10ae2257 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
	.../gcc/final.c:3152
0x10ade9a3 final_1
	.../gcc/final.c:2020
0x10ae6157 rest_of_handle_final
	.../gcc/final.c:4658
0x10ae6697 execute
	.../gcc/final.c:4736
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
compiler exited with status 1
FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)

triggered by an RTL instruction like:

(insn 97 96 98 (set (reg:SI 5 %r5 [88])
        (zero_extract:SI (mem/c:SI (symbol_ref:SI ("b") <var_decl 0x7ffff7f801b0 b>) [0 b+0 S4 A128])
            (const_int 8 [0x8])
            (const_int 24 [0x18]))) ".../gcc/testsuite/gcc.dg/torture/vshuf-main.inc":28:1 97 {*extzv_aligned}
     (nil))

and removes these regressions:

FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (test for excess errors)
FAIL: gcc.dg/torture/vshuf-v4hi.c   -O2  (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v4hi.c   -O2  (test for excess errors)
FAIL: gcc.dg/torture/vshuf-v8hi.c   -O2  (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v8hi.c   -O2  (test for excess errors)
FAIL: gcc.dg/torture/vshuf-v8qi.c   -O2  (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v8qi.c   -O2  (test for excess errors)

However expand typically presents pseudo-registers rather than memory
references to these insns, so a further rework is required to make a
better use of the code variant they are supposed to produce.  This at
least fixes the problem at hand.

	gcc/
	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
	(*extv_aligned): Also make sure the memory address of a bitfield
	location can be adjusted in the PIC mode.
---
 gcc/config/vax/vax.md | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 80f09d97727..f90ae89391f 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -762,11 +762,14 @@ (define_insn "*insv_aligned"
 			 (match_operand:QI 1 "const_int_operand" "n")
 			 (match_operand:SI 2 "const_int_operand" "n"))
 	(match_operand:SI 3 "general_operand" "g"))]
-   "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
+  "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
    && (!MEM_P (operands[0])
-       || ! mode_dependent_address_p (XEXP (operands[0], 0),
-				      MEM_ADDR_SPACE (operands[0])))
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[0], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[0], 0),
+					 MEM_ADDR_SPACE (operands[0]))))
    && (!(REG_P (operands[0])
 	 || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
        || INTVAL (operands[2]) == 0)"
@@ -794,8 +797,11 @@ (define_insn "*extzv_aligned"
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    && (!MEM_P (operands[1])
-       || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[1], 0),
+					 MEM_ADDR_SPACE (operands[1]))))
    && (!(REG_P (operands[1])
 	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
@@ -822,8 +828,11 @@ (define_insn "*extv_aligned"
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    && (!MEM_P (operands[1])
-       || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[1], 0),
+					 MEM_ADDR_SPACE (operands[1]))))
    && (!(REG_P (operands[1])
 	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (21 preceding siblings ...)
  2020-11-20  3:35 ` [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21 17:26   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns Maciej W. Rozycki
                   ` (11 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

We have matching insns defined for `sign_extract' and `zero_extract'
expressions, so make the three named patterns for bitfield operations
consistent and make `extv' an expander rather than an insn taking a
SImode, a QImode, and a SImode general operand for the LOC, SIZE, and
POS operands respectively, like with the `extzv' and `insv' patterns,
matching the machine instructions and giving the middle end more choice
as to which actual insn to choose in a given situation.

Given this program:

typedef struct
{
  int f0:1;
  int f1:7;
  int f8:8;
  int f16:16;
} bit_t;

typedef struct
{
  unsigned int f0:1;
  unsigned int f1:7;
  unsigned int f8:8;
  unsigned int f16:16;
} ubit_t;

typedef union
{
  bit_t b;
  int i;
} bit_u;

typedef union
{
  ubit_t b;
  unsigned int i;
} ubit_u;

int
ins1 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f1 = y;
  return x.i;
}

int
ext1 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f1;
}

unsigned int
extz1 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f1;
}

int
ins8 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f8 = y;
  return x.i;
}

int
ext8 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f8;
}

unsigned int
extz8 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f8;
}

int
ins16 (bit_u x, int y)
{
  asm volatile ("" : "+r" (x), "+r" (y));
  x.b.f16 = y;
  return x.i;
}

int
ext16 (bit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f16;
}

unsigned int
extz16 (ubit_u x)
{
  asm volatile ("" : "+r" (x));
  return x.b.f16;
}

this results in the following code change:

@@ -16,12 +16,12 @@ ins1:
 .globl ext1
 	.type	ext1, @function
 ext1:
-	.word 0	# 19	[c=0]  procedure_entry_mask
-	subl2 $4,%sp	# 20	[c=32]  addsi3
+	.word 0	# 18	[c=0]  procedure_entry_mask
+	subl2 $4,%sp	# 19	[c=32]  addsi3
 	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
-	cvtbl %r0,%r0	# 7	[c=4]  extendqisi2
-	ashl $-1,%r0,%r0	# 14	[c=40]  *vax.md:624
-	ret		# 24	[c=0]  return
+	extv $1,$7,%r0,%r0	# 7	[c=60]  *extv_non_const
+	cvtbl %r0,%r0	# 13	[c=4]  extendqisi2
+	ret		# 23	[c=0]  return
 	.size	ext1, .-ext1
 	.align 1
 .globl extz1
@@ -49,12 +49,12 @@ ins8:
 .globl ext8
 	.type	ext8, @function
 ext8:
-	.word 0	# 20	[c=0]  procedure_entry_mask
-	subl2 $4,%sp	# 21	[c=32]  addsi3
+	.word 0	# 18	[c=0]  procedure_entry_mask
+	subl2 $4,%sp	# 19	[c=32]  addsi3
 	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
-	cvtwl %r0,%r0	# 7	[c=4]  extendhisi2
-	ashl $-8,%r0,%r0	# 15	[c=40]  *vax.md:624
-	ret		# 25	[c=0]  return
+	rotl $24,%r0,%r0	# 13	[c=60]  *extv_non_const
+	cvtbl %r0,%r0
+	ret		# 23	[c=0]  return
 	.size	ext8, .-ext8
 	.align 1
 .globl extz8

If there is a performance degradation with the replacement sequences,
then it can and should be sorted within `extv_non_const'.

	gcc/
	* config/vax/vax.md (extv): Rename insn to...
	(*extv): ... this.
	(extv): New expander.
---
 gcc/config/vax/vax.md | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index f90ae89391f..d8774cdd36c 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -941,7 +941,15 @@ (define_insn ""
   ""
   "cmpzv %2,%1,%0,%3")
 
-(define_insn "extv"
+(define_expand "extv"
+  [(set (match_operand:SI 0 "general_operand" "")
+	(sign_extract:SI (match_operand:SI 1 "general_operand" "")
+			 (match_operand:QI 2 "general_operand" "")
+			 (match_operand:SI 3 "general_operand" "")))]
+  ""
+  "")
+
+(define_insn "*extv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
 			 (match_operand:QI 2 "general_operand" "g")
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (22 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21 17:27   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns Maciej W. Rozycki
                   ` (10 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

It makes no sense for insn operand predicates, as long as they accept a
register operand, to be more restrictive than the set of the associated
constraints, because expand will choose the insn based on the relevant
operand being a pseudo register then and reload keep it happily as a
memory reference if a constraint permits it.  So the restriction posed
by such a predicate will be happily ignored, and moreover if a splitter
is added, such as required for MODE_CC support, the new instructions
will reject the original operands supplied, causing an ICE.  An actual
example will be given with a subsequent change.

Therefore, similarly to EXTV/EXTZV/INSV insns, remove inconsistencies
with predicates and constraints of bitfield comparison insns, observing
that a bitfield located in memory is byte-addressed by the respective
machine instructions and therefore SImode may only be used with a
register or an offsettable memory operand (i.e. not an indexed,
pre-decremented, or post-incremented one).

Also give the insns names, for easier reference here and elsewhere.

	gcc/
	* config/vax/vax.md (*cmpv_2): Name insn.
	(*cmpv, *cmpzv, *cmpzv_2): Likewise.  Fix location predicate and
	constraint.
---
 gcc/config/vax/vax.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index d8774cdd36c..34fdf67bb6d 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -853,20 +853,20 @@ (define_insn "*extv_aligned"
 \f
 ;; Register and non-offsettable-memory SImode cases of bit-field insns.
 
-(define_insn ""
+(define_insn "*cmpv"
   [(set (cc0)
 	(compare
-	 (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
+	 (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
   "cmpv %2,%1,%0,%3")
 
-(define_insn ""
+(define_insn "*cmpzv"
   [(set (cc0)
 	(compare
-	 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+	 (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
@@ -921,7 +921,7 @@ (define_insn "*extzv_non_const"
 ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
 ;; don't match these (and therefore match the cases above instead).
 
-(define_insn ""
+(define_insn "*cmpv_2"
   [(set (cc0)
 	(compare
 	 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
@@ -931,10 +931,10 @@ (define_insn ""
   ""
   "cmpv %2,%1,%0,%3")
 
-(define_insn ""
+(define_insn "*cmpzv_2"
   [(set (cc0)
 	(compare
-	 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
+	 (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (23 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21  4:05   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 26/31] VAX: Correct issues with commented-out insns Maciej W. Rozycki
                   ` (9 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

It makes no sense for insn operand predicates, as long as they accept a
register operand, to be more restrictive than the set of the associated
constraints, because expand will choose the insn based on the relevant
operand being a pseudo register then and reload will keep it happily as
an immediate if a constraint permits it.  So the restriction posed by
such a predicate will be happily ignored, and moreover if a splitter is
added, such as required for MODE_CC support, the new instructions will
reject the original operands supplied, causing an ICE like below:

.../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: Error: could not split insn
(insn 90 662 663 (set (reg:DI 10 %r10 [orig:97 _235 ] [97])
        (mult:DI (sign_extend:DI (mem/c:SI (plus:SI (reg/f:SI 13 %fp)
                        (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S4 A32]))
            (sign_extend:DI (const_int -51 [0xffffffffffffffcd])))) 299 {mulsidi3}
     (expr_list:REG_EQUAL (mult:DI (sign_extend:DI (subreg:SI (mem/c:DI (plus:SI (reg/f:SI 13 %fp)
                            (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S8 A32]) 0))
            (const_int -51 [0xffffffffffffffcd]))
        (nil)))
during RTL pass: final
.../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: internal compiler error: in final_scan_insn_1, at final.c:3073
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.

Change the predicates used with the widening multiply and multiply-add
insns to allow immediates then, just as the constraints and the machine
instructions produced permit.

Also give the insns names, for easier reference here and elsewhere.

	gcc/
	* config/vax/vax.md (mulsidi3): Fix the multiplicand predicates.
	(*maddsidi4, *maddsidi4_const): Likewise.  Name insns.
---
 gcc/config/vax/vax.md | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 34fdf67bb6d..2f6643abe5c 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -445,35 +445,32 @@ (define_insn "mul<mode>3"
 
 (define_insn "mulsidi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
-	(mult:DI (sign_extend:DI
-		  (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
-		 (sign_extend:DI
-		  (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))]
+	(mult:DI
+	  (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	  (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))]
   ""
   "emul %1,%2,$0,%0")
 
-(define_insn ""
+(define_insn "*maddsidi4"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(plus:DI
-	 (mult:DI (sign_extend:DI
-		   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
-		  (sign_extend:DI
-		   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
-	 (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
+	  (mult:DI
+	    (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	    (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+	  (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))]
   ""
   "emul %1,%2,%3,%0")
 
 ;; 'F' constraint means type CONST_DOUBLE
-(define_insn ""
+(define_insn "*maddsidi4_const"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(plus:DI
-	 (mult:DI (sign_extend:DI
-		   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
-		  (sign_extend:DI
-		   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
-	 (match_operand:DI 3 "immediate_operand" "F")))]
+	  (mult:DI
+	    (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	    (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+	  (match_operand:DI 3 "immediate_operand" "F")))]
   "GET_CODE (operands[3]) == CONST_DOUBLE
-    && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
+   && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
   "*
 {
   if (CONST_DOUBLE_HIGH (operands[3]))
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 26/31] VAX: Correct issues with commented-out insns
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (24 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21  4:05   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Maciej W. Rozycki
                   ` (8 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Correct issues with commented-out insns, which fail to build if enabled:

.../gcc/config/vax/vax.md:503:1: repeated operand number 1
.../gcc/config/vax/vax.md:503:1: repeated operand number 2

and then when the issue with the repeated operands has been corrected:

.../gcc/config/vax/vax.md:107:1: destination operand 0 allows non-lvalue
.../gcc/config/vax/vax.md:503:1: destination operand 0 allows non-lvalue
.../gcc/config/vax/vax.md:503:1: destination operand 3 allows non-lvalue
.../gcc/config/vax/vax.md:744:1: destination operand 0 allows non-lvalue

Fix the RTL with the repeated operands and change the relevant output
operand predicates not to allow immediates.

Also emit MOVO rather than MOVH assembly instruction with the `movti'
insn so that the condition codes are set according to the integer rather
than floating-point interpretation of the datum moved, as expected with
the operation associated with the pattern.

Finally give `*amulsi4' a name, for easier reference here and elsewhere.

We may eventually want to have some of these insns enabled at `-Os'.

ChangeLog:

	* gcc/config/vax/vax.md (movti): Fix output predicate.  Emit
	`movo' rather than `movh'.
	(divmoddisi4): Fix output predicates, correct RTL.
	(*amulsi4): Name insn.  Fix output predicate.
---
 gcc/config/vax/vax.md | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 2f6643abe5c..4b0c26d1d58 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -105,10 +105,10 @@ (define_insn "mov<mode>"
 
 ;; Some VAXen don't support this instruction.
 ;;(define_insn "movti"
-;;  [(set (match_operand:TI 0 "general_operand" "=g")
+;;  [(set (match_operand:TI 0 "nonimmediate_operand" "=g")
 ;;	(match_operand:TI 1 "general_operand" "g"))]
 ;;  ""
-;;  "movh %1,%0")
+;;  "movo %1,%0")
 
 (define_insn "movdi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
@@ -501,12 +501,12 @@ (define_insn "div<mode>3"
 ;This is left out because it is very slow;
 ;we are better off programming around the "lack" of this insn.
 ;(define_insn "divmoddisi4"
-;  [(set (match_operand:SI 0 "general_operand" "=g")
+;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;	(div:SI (match_operand:DI 1 "general_operand" "g")
 ;		(match_operand:SI 2 "general_operand" "g")))
-;   (set (match_operand:SI 3 "general_operand" "=g")
-;	(mod:SI (match_operand:DI 1 "general_operand" "g")
-;		(match_operand:SI 2 "general_operand" "g")))]
+;   (set (match_operand:SI 3 "nonimmediate_operand" "=g")
+;	(mod:SI (match_dup 1)
+;		(match_dup 2)))]
 ;  ""
 ;  "ediv %2,%1,%0,%3")
 \f
@@ -741,8 +741,8 @@ (define_insn ""
   "rotl %2,%1,%0")
 
 ;This insn is probably slower than a multiply and an add.
-;(define_insn ""
-;  [(set (match_operand:SI 0 "general_operand" "=g")
+;(define_insn "*amulsi4"
+;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
 ;			  (match_operand:SI 2 "general_operand" "g"))
 ;		 (match_operand:SI 3 "general_operand" "g")))]
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (25 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 26/31] VAX: Correct issues with commented-out insns Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21  4:06   ` Jeff Law
  2020-11-24  1:37   ` Segher Boessenkool
  2020-11-20  3:36 ` [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx Maciej W. Rozycki
                   ` (7 subsequent siblings)
  34 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Use a double colon to introduce the comments like elsewhere throughout
the VAX machine description.

	gcc/
	* config/vax/vax.md (divmoddisi4, *amulsi4): Make the comment
	notation consistent with the rest of the file.
---
 gcc/config/vax/vax.md | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 4b0c26d1d58..1bb4e300cae 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -498,17 +498,17 @@ (define_insn "div<mode>3"
    div<VAXint:isfx>2 %2,%0
    div<VAXint:isfx>3 %2,%1,%0")
 
-;This is left out because it is very slow;
-;we are better off programming around the "lack" of this insn.
-;(define_insn "divmoddisi4"
-;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-;	(div:SI (match_operand:DI 1 "general_operand" "g")
-;		(match_operand:SI 2 "general_operand" "g")))
-;   (set (match_operand:SI 3 "nonimmediate_operand" "=g")
-;	(mod:SI (match_dup 1)
-;		(match_dup 2)))]
-;  ""
-;  "ediv %2,%1,%0,%3")
+;; This is left out because it is very slow;
+;; we are better off programming around the "lack" of this insn.
+;;(define_insn "divmoddisi4"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;	(div:SI (match_operand:DI 1 "general_operand" "g")
+;;		(match_operand:SI 2 "general_operand" "g")))
+;;   (set (match_operand:SI 3 "nonimmediate_operand" "=g")
+;;	(mod:SI (match_dup 1)
+;;		(match_dup 2)))]
+;;  ""
+;;  "ediv %2,%1,%0,%3")
 \f
 ;; Bit-and on the VAX is done with a clear-bits insn.
 (define_expand "and<mode>3"
@@ -740,14 +740,14 @@ (define_insn ""
   ""
   "rotl %2,%1,%0")
 
-;This insn is probably slower than a multiply and an add.
-;(define_insn "*amulsi4"
-;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
-;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
-;			  (match_operand:SI 2 "general_operand" "g"))
-;		 (match_operand:SI 3 "general_operand" "g")))]
-;  ""
-;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
+;; This insn is probably slower than a multiply and an add.
+;;(define_insn "*amulsi4"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
+;;			  (match_operand:SI 2 "general_operand" "g"))
+;;		 (match_operand:SI 3 "general_operand" "g")))]
+;;  ""
+;;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
 \f
 ;; Special cases of bit-field insns which we should
 ;; recognize in preference to the general case.
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (26 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21 17:29   ` Jeff Law
  2020-11-20  3:36 ` [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant Maciej W. Rozycki
                   ` (6 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

The use of a constant double zero is required for post-reload compare
elimination to be able to discard redundant floating-point comparisons,
for example with a VAX RTL instruction stream like:

(insn 34 4 3 2 (parallel [
            (set (reg/v:DF 0 %r0 [orig:24 x ] [24])
                (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
                        (const_int 4 [0x4])) [1 x+0 S8 A32]))
            (clobber (reg:CC 16 %psl))
        ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 37 {*movdf}
     (nil))
(note 3 34 35 2 NOTE_INSN_FUNCTION_BEG)
(insn 35 3 36 2 (set (reg:CCZ 16 %psl)
        (compare:CCZ (reg/v:DF 0 %r0 [orig:24 x ] [24])
            (const_double:DF 0.0 [0x0.0p+0]))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 21 {*cmpdf_ccz}
     (nil))
(jump_insn 36 35 9 2 (set (pc)
        (if_then_else (eq (reg:CCZ 16 %psl)
                (const_int 0 [0]))
            (label_ref 11)
            (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz}
     (int_list:REG_BR_PROB 536870916 (nil))
 -> 11)

that we want to transform into:

(insn 34 4 3 2 (parallel [
            (set (reg:CCZ 16 %psl)
                (compare:CCZ (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
                            (const_int 4 [0x4])) [1 x+0 S8 A32])
                    (const_double:DF 0.0 [0x0.0p+0])))
            (set (reg/v:DF 0 %r0 [orig:24 x ] [24])
                (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
                        (const_int 4 [0x4])) [1 x+0 S8 A32]))
        ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 40 {*movdf_ccz}
     (nil))
(note 3 34 36 2 NOTE_INSN_FUNCTION_BEG)
(jump_insn 36 3 9 2 (set (pc)
        (if_then_else (eq (reg:CCZ 16 %psl)
                (const_int 0 [0]))
            (label_ref 11)
            (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz}
     (int_list:REG_BR_PROB 536870916 (nil))
 -> 11)

with the upcoming MODE_CC representation.

For this we need to express the `const_double:DF 0.0 [0x0.0p+0]' rtx as
recorded above in the relevant pattern(s) in machine description.  The
way we represent double constants, as a host-dependent number of wide
integers, however means that we currently have no portable way to encode
a double zero constant in machine description.

Define a syntactic rtx alias then to represent `(const_double 0 0 ...)'
as if the suitable number of zeros have been supplied according to the
host-specific definition of CONST_DOUBLE_FORMAT.

	gcc/
	* read-rtl.c (rtx_reader::read_rtx_code): Handle syntactic
	`const_double_zero' rtx.
	* doc/rtl.texi (Constant Expression Types): Document it.
---
 gcc/doc/rtl.texi | 18 ++++++++++++++++++
 gcc/read-rtl.c   | 10 ++++++++++
 2 files changed, 28 insertions(+)

diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 22af5731bb6..f7a715d93cb 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1705,6 +1705,24 @@ machine's or host machine's floating point format.  To convert them to
 the precise bit pattern used by the target machine, use the macro
 @code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}).
 
+@findex const_double_zero
+The host dependency for the number of integers used to store a double
+value makes it problematic for machine descriptions to use expressions
+of code @code{const_double} and therefore a syntactic alias has been
+provided:
+
+@smallexample
+(const_double_zero)
+@end smallexample
+
+standing for:
+
+@smallexample
+(const_double 0 0 @dots{})
+@end smallexample
+
+for matching the floating-point value zero, possibly the only useful one.
+
 @findex CONST_WIDE_INT
 @item (const_wide_int:@var{m} @var{nunits} @var{elt0} @dots{})
 This contains an array of @code{HOST_WIDE_INT}s that is large enough
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 403f254f3cb..2922af5d111 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -1651,6 +1651,16 @@ rtx_reader::read_rtx_code (const char *code_name)
       return return_rtx;
     }
 
+  /* Handle "const_double_zero".  */
+  if (strcmp (code_name, "const_double_zero") == 0)
+    {
+      code = CONST_DOUBLE;
+      return_rtx = rtx_alloc (code);
+      memset (return_rtx, 0, RTX_CODE_SIZE (code));
+      PUT_CODE (return_rtx, code);
+      return return_rtx;
+    }
+
   /* If we end up with an insn expression then we free this space below.  */
   return_rtx = rtx_alloc_for_name (code_name);
   code = GET_CODE (return_rtx);
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (27 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-21  4:07   ` Jeff Law
  2020-12-15  8:26   ` Martin Liška
  2020-11-20  3:36 ` [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation Maciej W. Rozycki
                   ` (5 subsequent siblings)
  34 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

We do not define a comparison operation between floating-point and
integer data, including integer zero constant.  Consequently the RTL
instruction stream presented to the post-reload comparison elimination
pass will include, where applicable, floating-point comparison insns
against `const_double:DF 0.0 [0x0.0p+0]' rather than `const_int 0 [0]',
meaning that the latter expression will not match when used in machine
description.

Use `const_double_zero' then for the relevant patterns to match the
intended RTL instructions.

	gcc/
	* config/pdp11/pdp11.md (fcc_cc, fcc_ccnz): Use
	`const_double_zero' to express double zero constant.
---
 gcc/config/pdp11/pdp11.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md
index 7a4d50fdba9..cdef49f3979 100644
--- a/gcc/config/pdp11/pdp11.md
+++ b/gcc/config/pdp11/pdp11.md
@@ -105,7 +105,7 @@ (define_subst "fcc_cc"
    (clobber (reg FCC_REGNUM))]
   ""
   [(set (reg:CC FCC_REGNUM)
-	(compare:CC (match_dup 1) (const_int 0)))
+	(compare:CC (match_dup 1) (const_double_zero)))
    (set (match_dup 0) (match_dup 1))])
 
 (define_subst "fcc_ccnz"
@@ -113,7 +113,7 @@ (define_subst "fcc_ccnz"
    (clobber (reg FCC_REGNUM))]
   ""
   [(set (reg:CCNZ FCC_REGNUM)
-	(compare:CCNZ (match_dup 1) (const_int 0)))
+	(compare:CCNZ (match_dup 1) (const_double_zero)))
    (set (match_dup 0) (match_dup 1))])
 
 (define_subst_attr "cc_cc" "cc_cc" "_nocc" "_cc")
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (28 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant Maciej W. Rozycki
@ 2020-11-20  3:36 ` Maciej W. Rozycki
  2020-11-22  3:27   ` Jeff Law
  2020-12-09 16:09   ` Maciej W. Rozycki
  2020-11-20  3:37 ` [PATCH 31/31] PR target/95294: VAX: Add test cases for " Maciej W. Rozycki
                   ` (4 subsequent siblings)
  34 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

In the VAX ISA INSV bitfield insert instruction is the only computational
operation that keeps the condition codes, held in the PSL or Processor
Status Longword register, intact.  The instruction is flexible enough it
could potentially be used for data moves post-reload, but then reportedly
it is not the best choice performance-wise, and then we have no addition
operation available that would keep the condition codes unchanged.

Futhermore, as usually with a complex CISC ISA, for many operations we
have several machine instructions or instruction sequences to choose
from that set condition codes in a different manner.

Use the approach then where the condition codes only get introduced by
reload, by definining instruction splitters for RTL insns that change
condition codes in some way, by default considering them clobbered.

Then to prevent code generated from regressing too much provide insns
that include a `compare' operation setting the condition codes in
parallel to the main operation.  The manner condition codes are set by
each insn is supposed to be provided by the whatever the SELECT_CC_MODE
macro expands to.

Given that individual patterns provided for the same RTL basic operation
may set the condion codes differently keeping the information away from
the insn patterns themselves would cause a maintenance nightmare and
would be bound to fail in a horrible way sooner or later.  Therefore
instead let the patterns themselves choose which condition modes they
support, by having one or more subst iterators applied and then have
individual comparison operators require the specific condition mode each
according to the codes used by the operation.

While subst iterators only support one alternative each, there is
actually no problem with applying multiple ones to a single insn with
the result as intended, and if the corresponding subst attribute
supplies an empty NO-SUBST-VALUE, then no mess results even.  Make use
of this observation.

Add appropriate subst iterators to all the computational patterns then,
according to the condition codes they usably set, including DImode ones
and a substitute DImode comparison instruction in the absence of a CMPQ
machine instruction, however do not provide a `cbranchdi4' named pattern
as without a further development it regresses code quality by resorting
to the `__cmpdi2' libcall where a simpler operation would do, e.g. to
check for negativity the TSTL machine instruction may be executed over
the upper longword only.  This is good material for further work.

Do not apply subst iterators to the increment- or decrement-and-branch
patterns at this time; these may yet have to be reviewed, in particular
whether `*jsobneq_minus_one' is still relevant in the context of the
recent integer constant cost review.

Also add a couple of peepholes to help eliminating comparisons in some
problematic cases, such as with the BIT instruction which is bitwise-AND
for condition codes only that has no direct counterpart for the actual
calculation, because the BIC instruction which does do bitwise-AND and
produces a result implements the operation with a bitwise negation of
its input `mask' operand.  Or the FFS instruction which sets the Z
condition code according to its `field' input operand rather than the
result produced.  Or the bitfield comparisons we don't have generic
middle-end support for.

Code size stats are as follows, obtained from 17640 and 9086 executables
built in `check-c' and `check-c++' GCC testing respectively:

                      check-c                 check-c++
              samples average  median  samples average  median
---------------------------------------------------------------
regressions      1813  0.578%  0.198%      289  0.349%  0.175%
unchanged       15160  0.000%  0.000%     8662  0.000%  0.000%
progressions      667 -0.589% -0.194%      135 -0.944% -0.191%
----------------------------------------------------------------
total           17640  0.037%  0.000%     9086 -0.003%  0.000%

Outliers:

old     new     change  %change filename
----------------------------------------------------
2406    2950    +544    +22.610 20111208-1.exe
4314    5329    +1015   +23.528 pr39417.exe
2235    3055    +820    +36.689 990404-1.exe
2631    4213    +1582   +60.129 pr57521.exe
3063    5579    +2516   +82.142 20000422-1.exe

and:

old     new     change  %change filename
----------------------------------------------------
6317    4845    -1472   -23.302 vector-compare-1.exe
6313    4845    -1468   -23.254 vector-compare-1.exe
6474    5002    -1472   -22.737 vector-compare-1.exe
6470    5002    -1468   -22.689 vector-compare-1.exe

We have some code quality regressions like:

    10861:	9e ef d9 12 	movab 11b40 <p>,r0
    10865:	00 00 50
    10868:	90 a0 03 a0 	movb 0x3(r0),0x2(r0)
    1086c:	02
    1086d:	d1 60 8f 61 	cmpl (r0),$0x64646261
    10871:	62 64 64
    10874:	13 07 		beql 1087d <main_test+0x21>

to:

    10861:	9e ef e1 12	movab 11b48 <p>,r0
    10865:	00 00 50
    10868:	90 a0 03 a0 	movb 0x3(r0),0x2(r0)
    1086c:	02
    1086d:	d1 ef d5 12 	cmpl 11b48 <p>,$0x64646261
    10871:	00 00 8f 61
    10875:	62 64 64
    10878:	13 07 		beql 10881 <main_test+0x25>

(from `memmove-2.x2') due to the constant propagation passes eagerly
replacing pseudo registers with direct symbol references where possible,
which does not happen with CC0 even though the passes do run regardless.

There are further code quality regressions due to earlier compilation
stages trying to push expression evaluation earlier where possible so
as to make data dependencies further apart from each other.  This works
well for computations and architectures that do not involve condition
codes set as a side effect of calculations.  However for integer
negation that makes assembly code produced like:

	movb *8(%ap),%r0
	mnegb %r0,%r1
	tstb %r0
	jeql .L2

the RTL equibvalent of which the comparison elimination pass cannot
really do anything about, because the comparison is made on the source
rather than the target operand of the negation (we could add a peephole
for this, but this seems futile an effort, as one'd have to iterate over
all the possible such cases), even though this is really equivalent to:

	movb *8(%ap),%r0
	mnegb %r0,%r1
	jeql .L2

or, if R0 is dead at the conclusion of the branch, even:

	mnegb *8(%ap),%r1
	jeql .L2

Since the compiler insists on doing the comparison on the source of the
negation it obviously has to load it into a temporary so as to avoid
accessing the original memory location twice, hence the sequence of
three instructions rather than just a single one.  A similar phenomenon
can be observed with the XOR operation and in other cases.

In some cases a comparison does get eliminated, however useless moves
into registers done in preparation to it remain, such as with:

	movb *8(%ap),%r2
	movb *12(%ap),%r1
	subb3 %r1,%r2,%r0
	jlssu .L2

where R1 and R2 are both dead at conclusion and therefore:

	subb3 *12(%ap),*8(%ap),%r0
	jlssu .L2

would obviously do, but there was to be a comparison before the branch:

	cmpb %r2,%r1

All this looks like material for future improvement.

Test cases for comparison elimination and the peepholes will be supplied
separately.

	gcc/
	PR target/95294
	* config/vax/elf.h (REGISTER_NAMES): Append `%psl'.
	* config/vax/vax-modes.def (CCN, CCNZ, CCZ): New modes.
	* config/vax/vax-protos.h (vax_select_cc_mode): New prototype.
	(vax_maybe_split_dimode_move): Likewise.
	(vax_notice_update_cc): Remove prototype.
	* config/vax/vax.c (TARGET_FLAGS_REGNUM): New macro.
	(TARGET_CC_MODES_COMPATIBLE): Likewise.
	(TARGET_MD_ASM_ADJUST): Likewise.
	(vax_select_cc_mode): New function
	(vax_cc_modes_compatible): Likewise.
	(vax_md_asm_adjust): Likewise.
	(vax_notice_update_cc): Remove function.
	(vax_output_int_move): Factor out code checking if a DImode move
	may have to be split...
	(vax_maybe_split_dimode_move): ... into this new function.
	* config/vax/vax.h (FIRST_PSEUDO_REGISTER): Bump up.
	(FIXED_REGISTERS): Append an entry for PSL.
	(CALL_USED_REGISTERS): Likewise.
	(NOTICE_UPDATE_CC, OUTPUT_JUMP): Remove macros.
	(SELECT_CC_MODE): New macro.
	(REGISTER_NAMES): Append `psl'.
	* config/vax/predicates.md (const_zero_operand)
	(vax_cc_comparison_operator, vax_ccn_comparison_operator)
	(vax_ccnz_comparison_operator, vax_ccz_comparison_operator):
	New predicates.
	* config/vax/builtins.md: Rewrite for MODE_CC representation.
	* config/vax/vax.md: Likewise.
---
 gcc/config/vax/builtins.md   |  109 ++-
 gcc/config/vax/elf.h         |    3 +-
 gcc/config/vax/predicates.md |   20 +
 gcc/config/vax/vax-modes.def |   11 +
 gcc/config/vax/vax-protos.h  |    3 +-
 gcc/config/vax/vax.c         |  203 +++--
 gcc/config/vax/vax.h         |   32 +-
 gcc/config/vax/vax.md        | 1788 ++++++++++++++++++++++++++++++++++++++----
 8 files changed, 1904 insertions(+), 265 deletions(-)

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index e96ac3f52ab..846d1f352ff 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -39,10 +39,10 @@ (define_expand "ffs<mode>2"
 {
   rtx label = gen_label_rtx ();
   rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
-  rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
+  rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx);
   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
 
-  emit_insn (gen_ctz<mode>2 (operands[0], operands[1]));
+  emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1]));
   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
   emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
   emit_label (label);
@@ -50,33 +50,114 @@ (define_expand "ffs<mode>2"
   DONE;
 }")
 
-(define_insn "ctz<mode>2"
+(define_insn_and_split "ctz<mode>2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+	(ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
+  ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ctz:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ctz<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
 	(ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
-   (set (cc0)
-	(compare (match_dup 1)
-		 (const_int 0)))]
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "ffs $0,$<width>,%1,%0")
+
+(define_insn_and_split "ctz<mode>2_ccz"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+	(ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+	   (compare:CCZ (match_dup 1)
+			(const_int 0)))
+      (set (match_dup 0)
+	   (ctz:SI (match_dup 1)))])]
+  "")
+
+(define_insn "*ctz<mode>2_ccz"
+  [(set (reg:CCZ VAX_PSL_REGNUM)
+	(compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT")
+		     (const_int 0)))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+	(ctz:SI (match_dup 1)))]
+  "reload_completed"
   "ffs $0,$<width>,%1,%0")
 
 ;; Our FFS hardware instruction supports any field width,
 ;; so handle narrower inputs directly as well.
 (define_peephole2
-  [(set (match_operand:SI 0 "register_operand")
-        (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+	   (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
    (parallel
      [(set (match_operand:SI 2 "nonimmediate_operand")
 	   (ctz:SI (match_dup 0)))
-      (set (cc0)
-	   (compare (match_dup 2)
-		    (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
   "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])"
   [(parallel
      [(set (match_dup 2)
 	   (ctz:SI (match_dup 1)))
-      (set (cc0)
-	   (compare (match_dup 1)
-		    (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+;; The FFS hardware instruction sets the Z condition code based on
+;; the input field rather than the output operand, so the compare
+;; elimination pass cannot handle it.  Try to get rid of the extra
+;; operation by hand.
+;;
+;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to
+;; have a mode dependent address, so all we need to verify is that
+;; the two operands are not the same, in which case it's the FFS
+;; output rather than input that condition codes are checked for.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "nonimmediate_operand")
+	   (ctz:SI (match_operand:VAXint 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+	(compare:CCZ (match_dup 1)
+		     (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[1])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+	   (compare:CCZ (match_dup 1)
+			(const_int 0)))
+      (set (match_dup 0)
+	   (ctz:SI (match_dup 1)))])]
+  "")
+
+;; This effectively combines the two peepholes above,
+;; matching the sequence produced by `ffs<mode>2'.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+	   (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (parallel
+     [(set (match_operand:SI 2 "nonimmediate_operand")
+	   (ctz:SI (match_dup 0)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+	(compare:CCZ (match_dup 0)
+		     (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[2])
+   && peep2_reg_dead_p (3, operands[0])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+	   (compare:CCZ (match_dup 1)
+			(const_int 0)))
+      (set (match_dup 2)
+	   (ctz:SI (match_dup 1)))])]
   "")
 
 (define_expand "sync_lock_test_and_set<mode>"
diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h
index 555ccef0921..52d340b53ed 100644
--- a/gcc/config/vax/elf.h
+++ b/gcc/config/vax/elf.h
@@ -26,7 +26,8 @@ along with GCC; see the file COPYING3.  If not see
 #define REGISTER_PREFIX "%"
 #define REGISTER_NAMES \
   { "%r0", "%r1",  "%r2",  "%r3", "%r4", "%r5", "%r6", "%r7", \
-    "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", }
+    "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", \
+    "%psl" }
 
 #undef SIZE_TYPE
 #define SIZE_TYPE "long unsigned int"
diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md
index 7c97b366604..92caf8384fa 100644
--- a/gcc/config/vax/predicates.md
+++ b/gcc/config/vax/predicates.md
@@ -17,6 +17,10 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+;; Return true if OP is a constant zero operand.
+(define_predicate "const_zero_operand"
+  (match_test "op == CONST0_RTX (mode)"))
+
 ;; Special case of a symbolic operand that's used as a
 ;; operand.
 
@@ -109,3 +113,19 @@ (define_predicate "volatile_mem_operand"
 (define_predicate "any_memory_operand"
   (ior (match_operand 0 "memory_operand")
        (match_operand 0 "volatile_mem_operand")))
+
+;; Return true if OP is a comparison operator that requires at least CCmode.
+(define_predicate "vax_cc_comparison_operator"
+  (match_code "geu,gtu,leu,ltu"))
+
+;; Return true if OP is a comparison operator that requires at least CCNmode.
+(define_predicate "vax_ccn_comparison_operator"
+  (match_code "ge,lt"))
+
+;; Return true if OP is a comparison operator that requires at least CCNZmode.
+(define_predicate "vax_ccnz_comparison_operator"
+  (match_code "gt,le"))
+
+;; Return true if OP is a comparison operator that requires at least CCZmode.
+(define_predicate "vax_ccz_comparison_operator"
+  (match_code "ne,eq"))
diff --git a/gcc/config/vax/vax-modes.def b/gcc/config/vax/vax-modes.def
index 5f1c9946653..2a7438ee77f 100644
--- a/gcc/config/vax/vax-modes.def
+++ b/gcc/config/vax/vax-modes.def
@@ -20,3 +20,14 @@ along with GCC; see the file COPYING3.  If not see
 /* We just need to reset the floating point formats.  */
 RESET_FLOAT_FORMAT (SF, vax_f_format);
 RESET_FLOAT_FORMAT (DF, vax_d_format);
+
+/* `DImode' addition and subtraction operations do their calculation
+   on the low and then the high longword with separate instructions,
+   and therefore only usably set N.  */
+CC_MODE (CCN);
+/* Non-arithmetic integer instructions such as MOV or XOR as well as
+   instructions that produce a floating-point result only usably set
+   N and Z.  */
+CC_MODE (CCNZ);
+/* The FFC and FFS instructions only usably set Z.  */
+CC_MODE (CCZ);
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index 454d35e3383..aa949c598d7 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -22,13 +22,14 @@ extern void vax_expand_prologue (void);
 
 #ifdef RTX_CODE
 extern bool vax_acceptable_pic_operand_p (rtx, bool, bool);
+extern machine_mode vax_select_cc_mode (enum rtx_code, rtx, rtx);
 extern const char *cond_name (rtx);
 extern bool adjacent_operands_p (rtx, rtx, machine_mode);
 extern const char *rev_cond_name (rtx);
 extern void print_operand_address (FILE *, rtx);
 extern void print_operand (FILE *, rtx, int);
-extern void vax_notice_update_cc (rtx, rtx);
 extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code);
+extern bool vax_maybe_split_dimode_move (rtx *);
 extern const char * vax_output_int_move (rtx, rtx *, machine_mode);
 extern const char * vax_output_int_add (rtx_insn *, rtx *, machine_mode);
 extern const char * vax_output_int_subtract (rtx_insn *, rtx *, machine_mode);
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 69a05b33e95..54d83dc1da2 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -54,6 +54,10 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
 static int vax_address_cost_1 (rtx);
 static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
 static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode);
+static rtx_insn *vax_md_asm_adjust (vec<rtx> &, vec<rtx> &,
+				    vec<const char *> &,
+				    vec<rtx> &, HARD_REG_SET &);
 static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
 static void vax_function_arg_advance (cumulative_args_t,
 				      const function_arg_info &);
@@ -81,11 +85,23 @@ static HOST_WIDE_INT vax_starting_frame_offset (void);
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
 
+/* Enable compare elimination pass.  */
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM VAX_PSL_REGNUM
+
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS vax_rtx_costs
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST vax_address_cost
 
+/* Return the narrowest CC mode that spans both modes offered.  */
+#undef TARGET_CC_MODES_COMPATIBLE
+#define TARGET_CC_MODES_COMPATIBLE vax_cc_modes_compatible
+
+/* Mark PSL as clobbered for compatibility with the CC0 representation.  */
+#undef TARGET_MD_ASM_ADJUST
+#define TARGET_MD_ASM_ADJUST vax_md_asm_adjust
+
 #undef TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
 
@@ -1070,6 +1086,102 @@ vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED,
   return true;
 }
 \f
+/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE,
+   return the mode to be used for the comparison.  As we have the same
+   interpretation of condition codes across all the instructions we just
+   return the narrowest mode suitable for the comparison code requested.  */
+
+extern machine_mode
+vax_select_cc_mode (enum rtx_code op,
+		    rtx x ATTRIBUTE_UNUSED, rtx y ATTRIBUTE_UNUSED)
+{
+  switch (op)
+    {
+    default:
+      gcc_unreachable ();
+    case NE:
+    case EQ:
+      return CCZmode;
+    case GE:
+    case LT:
+      return CCNmode;
+    case GT:
+    case LE:
+      return CCNZmode;
+    case GEU:
+    case GTU:
+    case LEU:
+    case LTU:
+      return CCmode;
+    }
+}
+
+/* Return the narrowest CC mode that spans both modes offered.  If they
+   intersect, this will be the wider of the two, and if they do not then
+   find find one that is a superset of both (i.e. CCNZmode for a pair
+   consisting of CCNmode and CCZmode).  A wider CC writer will satisfy
+   a narrower CC reader, e.g. a comparison operator that uses CCZmode
+   can use a CCNZmode output of a previous instruction.  */
+
+static machine_mode
+vax_cc_modes_compatible (machine_mode m1, machine_mode m2)
+{
+  switch (m1)
+    {
+    default:
+      gcc_unreachable ();
+    case E_CCmode:
+      switch (m2)
+	{
+	default:
+	  gcc_unreachable ();
+	case E_CCmode:
+	case E_CCNZmode:
+	case E_CCNmode:
+	case E_CCZmode:
+	  return m1;
+	}
+    case E_CCNZmode:
+      switch (m2)
+	{
+	default:
+	  gcc_unreachable ();
+	case E_CCmode:
+	  return m2;
+	case E_CCNmode:
+	case E_CCNZmode:
+	case E_CCZmode:
+	  return m1;
+	}
+    case E_CCNmode:
+    case E_CCZmode:
+      switch (m2)
+	{
+	default:
+	  gcc_unreachable ();
+	case E_CCmode:
+	case E_CCNZmode:
+	  return m2;
+	case E_CCNmode:
+	case E_CCZmode:
+	  return m1 == m2 ? m1 : E_CCNZmode;
+	}
+    }
+}
+\f
+/* Mark PSL as clobbered for compatibility with the CC0 representation.  */
+
+static rtx_insn *
+vax_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
+		   vec<rtx> &inputs ATTRIBUTE_UNUSED,
+		   vec<const char *> &constraints ATTRIBUTE_UNUSED,
+		   vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs)
+{
+  clobbers.safe_push (gen_rtx_REG (CCmode, VAX_PSL_REGNUM));
+  SET_HARD_REG_BIT (clobbered_regs, VAX_PSL_REGNUM);
+  return NULL;
+}
+\f
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.
 	.mask	^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>  #conservative entry mask
@@ -1102,81 +1214,21 @@ vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
   return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
 }
 
-/* Worker function for NOTICE_UPDATE_CC.  */
+/* Output integer move instructions.  */
 
-void
-vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
+bool
+vax_maybe_split_dimode_move (rtx *operands)
 {
-  if (GET_CODE (exp) == SET)
-    {
-      if (GET_CODE (SET_SRC (exp)) == CALL)
-	CC_STATUS_INIT;
-      else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
-	       && GET_CODE (SET_DEST (exp)) != PC)
-	{
-	  cc_status.flags = 0;
-	  /* The integer operations below don't set carry or
-	     set it in an incompatible way.  That's ok though
-	     as the Z bit is all we need when doing unsigned
-	     comparisons on the result of these insns (since
-	     they're always with 0).  Set CC_NO_OVERFLOW to
-	     generate the correct unsigned branches.  */
-	  switch (GET_CODE (SET_SRC (exp)))
-	    {
-	    case NEG:
-	      if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
-		break;
-	      /* FALLTHRU */
-	    case AND:
-	    case IOR:
-	    case XOR:
-	    case NOT:
-	    case MEM:
-	    case REG:
-	      cc_status.flags = CC_NO_OVERFLOW;
-	      break;
-	    case CTZ:
-	      cc_status.flags = CC_NOT_NEGATIVE;
-	      break;
-	    default:
-	      break;
-	    }
-	  cc_status.value1 = SET_DEST (exp);
-	  cc_status.value2 = SET_SRC (exp);
-	}
-    }
-  else if (GET_CODE (exp) == PARALLEL
-	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
-    {
-      if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
-	CC_STATUS_INIT;
-      else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
-	{
-	  cc_status.flags = 0;
-	  cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
-	  cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
-	}
-      else
-	/* PARALLELs whose first element sets the PC are aob,
-	   sob insns.  They do change the cc's.  */
-	CC_STATUS_INIT;
-    }
-  else
-    CC_STATUS_INIT;
-  if (cc_status.value1 && REG_P (cc_status.value1)
-      && cc_status.value2
-      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
-    cc_status.value2 = 0;
-  if (cc_status.value1 && MEM_P (cc_status.value1)
-      && cc_status.value2
-      && MEM_P (cc_status.value2))
-    cc_status.value2 = 0;
-  /* Actual condition, one line up, should be that value2's address
-     depends on value1, but that is too much of a pain.  */
+  return (TARGET_QMATH
+	  && (!MEM_P (operands[0])
+	      || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
+	      || GET_CODE (XEXP (operands[0], 0)) == POST_INC
+	      || !illegal_addsub_di_memory_operand (operands[0], DImode))
+	  && ((CONST_INT_P (operands[1])
+	       && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
+	      || GET_CODE (operands[1]) == CONST_DOUBLE));
 }
 
-/* Output integer move instructions.  */
-
 const char *
 vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
 		     machine_mode mode)
@@ -1252,14 +1304,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
 	    }
 	}
 
-      if (TARGET_QMATH
-	  && (!MEM_P (operands[0])
-	      || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
-	      || GET_CODE (XEXP (operands[0], 0)) == POST_INC
-	      || !illegal_addsub_di_memory_operand (operands[0], DImode))
-	  && ((CONST_INT_P (operands[1])
-	       && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
-	      || GET_CODE (operands[1]) == CONST_DOUBLE))
+      if (vax_maybe_split_dimode_move (operands))
 	{
 	  hi[0] = operands[0];
 	  hi[1] = operands[1];
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index 43182ff1d88..8b2b2d17704 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -120,12 +120,12 @@ along with GCC; see the file COPYING3.  If not see
    from 0 to just below FIRST_PSEUDO_REGISTER.
    All registers that the compiler knows about must be given numbers,
    even those that are not normally considered general registers.  */
-#define FIRST_PSEUDO_REGISTER 16
+#define FIRST_PSEUDO_REGISTER 17
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
    On the VAX, these are the AP, FP, SP and PC.  */
-#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -133,7 +133,7 @@ along with GCC; see the file COPYING3.  If not see
    The latter must include the registers where values are returned
    and the register where structure-value addresses are passed.
    Aside from that, you can include as many other registers as you like.  */
-#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -465,24 +465,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 #define BRANCH_COST(speed_p, predictable_p) 0
 \f
-/* Tell final.c how to eliminate redundant test instructions.  */
-
-/* Here we define machine-dependent flags and fields in cc_status
-   (see `conditions.h').  No extra ones are needed for the VAX.  */
-
-/* Store in cc_status the expressions
-   that the condition codes will describe
-   after execution of an instruction whose pattern is EXP.
-   Do not alter them if the instruction would not alter the cc's.  */
-
-#define NOTICE_UPDATE_CC(EXP, INSN)	\
-  vax_notice_update_cc ((EXP), (INSN))
-
-#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)	\
-  { if (cc_status.flags & CC_NO_OVERFLOW)	\
-      return NO_OV;				\
-    return NORMAL;				\
-  }
+/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE,
+   return the mode to be used for the comparison.  As we have the same
+   interpretation of condition codes across all the instructions we just
+   return the narrowest mode suitable for the comparison code requested.  */
+#define SELECT_CC_MODE(OP, X, Y) vax_select_cc_mode (OP, X, Y)
 \f
 /* Control the assembler format that we output.  */
 
@@ -517,7 +504,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 #define REGISTER_PREFIX ""
 #define REGISTER_NAMES					\
   { "r0", "r1",  "r2",  "r3", "r4", "r5", "r6", "r7",	\
-    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", }
+    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",	\
+    "psl" }
 
 /* This is BSD, so it wants DBX format.  */
 
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index 1bb4e300cae..b8cf4eed4bc 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -22,9 +22,6 @@
 ;;- the first one in the file is chosen.
 ;;-
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
-;;-
-;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
-;;- updates for most instructions.
 
 ;; UNSPEC_VOLATILE usage:
 
@@ -40,6 +37,8 @@ (define_constants
    (VAX_FP_REGNUM 13)	    ; Register 13 contains the frame pointer
    (VAX_SP_REGNUM 14)	    ; Register 14 contains the stack pointer
    (VAX_PC_REGNUM 15)	    ; Register 15 contains the program counter
+   (VAX_PSL_REGNUM 16)	    ; Register 16 contains the processor status
+			    ; and condition codes in particular
   ]
 )
 
@@ -57,34 +56,96 @@ (define_mode_attr  fsfx [(SF "f") (DF "%#")])
 ;; Some output patterns want integer immediates with a prefix...
 (define_mode_attr  iprefx [(QI "B") (HI "H") (SI "N")])
 
+(define_mode_iterator VAXcc [CC CCN CCNZ CCZ])
+(define_mode_iterator VAXccnz [CCN CCNZ CCZ])
+(define_mode_attr cc [(CC "cc") (CCN "ccn") (CCNZ "ccnz") (CCZ "ccz")])
+
+(define_code_iterator any_extract [sign_extract zero_extract])
+
 ;;
 (include "constraints.md")
 (include "predicates.md")
 
-(define_insn "*cmp<mode>"
-  [(set (cc0)
-	(compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
-		 (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
+;; Make instructions that set the N, N+Z, and Z condition codes respectively.
+(define_subst "subst_<cc>"
+  [(set (match_operand 0 "")
+	(match_operand 1 ""))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
   ""
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz (match_dup 1)
+			 (const_int 0)))
+   (set (match_dup 0)
+	(match_dup 1))])
+
+(define_subst "subst_f<cc>"
+  [(set (match_operand 0 "")
+	(match_operand 1 ""))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  ""
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz (match_dup 1)
+			 (const_double_zero)))
+   (set (match_dup 0)
+	(match_dup 1))])
+
+;; Select all from the attributes below that apply to a given insn that
+;; has a clobber on CC for the comparison elimination pass to use it in
+;; place of a subsequent comparison instruction matching the mode used
+;; by a comparison operator in branch.
+;;
+;; For example a branch doing `eq' in SImode will use `*cmpsi_ccz', so
+;; to eliminate it a `*movsi_ccz', etc. pattern will be required via the
+;; `ccz' substitution.  Analogously for the other CC modes.
+;;
+;; The general `cc' mode, which sets all of the C, N, V and Z condition
+;; codes, has to be handled specially as it makes no sense for the usual
+;; comparison against zero, so no substitution has been defined for it.
+(define_subst_attr "ccn" "subst_ccn" "" "_ccn")
+(define_subst_attr "ccnz" "subst_ccnz" "" "_ccnz")
+(define_subst_attr "ccz" "subst_ccz" "" "_ccz")
+(define_subst_attr "fccn" "subst_fccn" "" "_ccn")
+(define_subst_attr "fccnz" "subst_fccnz" "" "_ccnz")
+(define_subst_attr "fccz" "subst_fccz" "" "_ccz")
+
+(define_insn "*cmp<VAXint:mode>_<VAXcc:mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc (match_operand:VAXint 0 "general_operand" "nrmT,nrmT")
+		       (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
+  "reload_completed"
   "@
    tst<VAXint:isfx> %0
    cmp<VAXint:isfx> %0,%1")
 
-(define_insn "*cmp<mode>"
-  [(set (cc0)
-	(compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
-		 (match_operand:VAXfp 1 "general_operand" "G,gF")))]
-  ""
+;; We don't have a CMPQ instruction, but we can set the N and Z condition
+;; codes with MOVQ, and also this comparison can be folded into a preceding
+;; operation by the post-reload comparison elimination pass.
+(define_insn "*cmpdi_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz (match_operand:DI 0 "general_operand" "r,nmT")
+			 (match_operand:DI 1 "const_zero_operand" "I,I")))
+   (clobber (match_scratch:DI 2 "=X,r"))]
+  "reload_completed"
+  "@
+   movq %0,%0
+   movq %0,%2")
+
+(define_insn "*cmp<VAXfp:mode>_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz (match_operand:VAXfp 0 "general_operand" "gF,gF")
+			 (match_operand:VAXfp 1 "general_operand" "G,gF")))]
+  "reload_completed"
   "@
    tst<VAXfp:fsfx> %0
    cmp<VAXfp:fsfx> %0,%1")
 
-(define_insn "*bit<mode>"
-  [(set (cc0)
-	(compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
-			     (match_operand:VAXint 1 "general_operand" "nrmT"))
-		 (const_int 0)))]
-  ""
+(define_insn "*bit<VAXint:mode>_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz
+	  (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
+		      (match_operand:VAXint 1 "general_operand" "nrmT"))
+	  (const_int 0)))]
+  "reload_completed"
   "bit<VAXint:isfx> %0,%1")
 
 ;; The VAX has no sCOND insns.  It does have add/subtract with carry
@@ -95,25 +156,76 @@ (define_insn "*bit<mode>"
 ;; and has been deleted.
 
 \f
-(define_insn "mov<mode>"
+(define_insn_and_split "mov<mode>"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
 	(match_operand:VAXfp 1 "general_operand" "G,gF"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mov<mode><fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+	(match_operand:VAXfp 1 "general_operand" "G,gF"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    clr<VAXfp:fsfx> %0
    mov<VAXfp:fsfx> %1,%0")
 
 ;; Some VAXen don't support this instruction.
-;;(define_insn "movti"
+;;(define_insn_and_split "movti"
 ;;  [(set (match_operand:TI 0 "nonimmediate_operand" "=g")
 ;;	(match_operand:TI 1 "general_operand" "g"))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;	   (match_dup 1))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*movti<ccn><ccnz><ccz>"
+;;  [(set (match_operand:TI 0 "nonimmediate_operand" "=g")
+;;	(match_operand:TI 1 "general_operand" "g"))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "movo %1,%0")
 
-(define_insn "movdi"
+(define_insn_and_split "movdi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(match_operand:DI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+;; In some cases `vax_output_int_move' splits a `DImode' move into a pair
+;; of `SImode' moves, in which case the flags aren't usefully set.  Have
+;; separate patterns then, for the cases where the move may and may not be
+;; split each.  We use the outer condition only so in some cases we will
+;; fail to notice the move does not actually get split, but this is OK.
+(define_insn "*movdi_maybe_split"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(match_operand:DI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed && vax_maybe_split_dimode_move (operands)"
+  "* return vax_output_int_move (insn, operands, DImode);")
+
+(define_insn "*movdi_unsplit<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(match_operand:DI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed && !vax_maybe_split_dimode_move (operands)"
   "* return vax_output_int_move (insn, operands, DImode);")
 
 ;; The VAX move instructions have space-time tradeoffs.  On a MicroVAX
@@ -155,22 +267,61 @@ (define_expand "movsi"
 #endif
 }")
 
-(define_insn "movsi_2"
+(define_insn_and_split "movsi_2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsi_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(match_operand:SI 1 "nonsymbolic_operand" "nrmT"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_move (insn, operands, SImode);")
 
-(define_insn "mov<mode>"
+(define_insn_and_split "mov<mode>"
   [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
 	(match_operand:VAXintQH 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mov<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
+	(match_operand:VAXintQH 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_move (insn, operands, <MODE>mode);")
 
-(define_insn "movstricthi"
-  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
+(define_insn_and_split "movstricthi"
+  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
 	(match_operand:HI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (strict_low_part (match_dup 0))
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movstricthi<ccn><ccnz><ccz>"
+  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
+	(match_operand:HI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (CONST_INT_P (operands[1]))
@@ -188,10 +339,23 @@ (define_insn "movstricthi"
   return \"movw %1,%0\";
 }")
 
-(define_insn "movstrictqi"
-  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
+(define_insn_and_split "movstrictqi"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
 	(match_operand:QI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (strict_low_part (match_dup 0))
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movstrictqi<ccn><ccnz><ccz>"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
+	(match_operand:QI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (CONST_INT_P (operands[1]))
@@ -236,7 +400,7 @@ (define_expand "movmemhi"
 ;; that anything generated as this insn will be recognized as one
 ;; and that it won't successfully combine with anything.
 
-(define_insn "movmemhi1"
+(define_insn_and_split "movmemhi1"
   [(set (match_operand:BLK 0 "memory_operand" "=o")
 	(match_operand:BLK 1 "memory_operand" "o"))
    (use (match_operand:HI 2 "general_operand" "g"))
@@ -247,90 +411,286 @@ (define_insn "movmemhi1"
    (clobber (reg:SI 4))
    (clobber (reg:SI 5))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (use (match_dup 2))
+      (clobber (reg:SI 0))
+      (clobber (reg:SI 1))
+      (clobber (reg:SI 2))
+      (clobber (reg:SI 3))
+      (clobber (reg:SI 4))
+      (clobber (reg:SI 5))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movmemhi1"
+  [(set (match_operand:BLK 0 "memory_operand" "=o")
+	(match_operand:BLK 1 "memory_operand" "o"))
+   (use (match_operand:HI 2 "general_operand" "g"))
+   (clobber (reg:SI 0))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI 2))
+   (clobber (reg:SI 3))
+   (clobber (reg:SI 4))
+   (clobber (reg:SI 5))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movc3 %2,%1,%0")
 \f
 ;; Extension and truncation insns.
 
-(define_insn "truncsiqi2"
+(define_insn_and_split "truncsiqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
 	(truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (truncate:QI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncsiqi2<ccn><ccnz><ccz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+	(truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtlb %1,%0")
 
-(define_insn "truncsihi2"
+(define_insn_and_split "truncsihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
 	(truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (truncate:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncsihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+	(truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))
+      (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtlw %1,%0")
 
-(define_insn "trunchiqi2"
+(define_insn_and_split "trunchiqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
 	(truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (truncate:QI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*trunchiqi2<ccn><ccnz><ccz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+	(truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtwb %1,%0")
 
-(define_insn "extendhisi2"
+(define_insn_and_split "extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendhisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtwl %1,%0")
 
-(define_insn "extendqihi2"
+(define_insn_and_split "extendqihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
 	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extend:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendqihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtbw %1,%0")
 
-(define_insn "extendqisi2"
+(define_insn_and_split "extendqisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendqisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtbl %1,%0")
 
-(define_insn "extendsfdf2"
+(define_insn_and_split "extendsfdf2"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
 	(float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (float_extend:DF (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendsfdf2<fccn><fccnz><fccz>"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
+	(float_extend:DF (match_operand:SF 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtf%# %1,%0")
 
-(define_insn "truncdfsf2"
+(define_insn_and_split "truncdfsf2"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
 	(float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (float_truncate:SF (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncdfsf2<fccn><fccnz><fccz>"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
+	(float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt%#f %1,%0")
 
-(define_insn "zero_extendhisi2"
+(define_insn_and_split "zero_extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendhisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzwl %1,%0")
 
-(define_insn "zero_extendqihi2"
+(define_insn_and_split "zero_extendqihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
 	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extend:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendqihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzbw %1,%0")
 
-(define_insn "zero_extendqisi2"
+(define_insn_and_split "zero_extendqisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendqisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzbl %1,%0")
 \f
 ;; Fix-to-float conversion insns.
 
-(define_insn "float<VAXint:mode><VAXfp:mode>2"
+(define_insn_and_split "float<VAXint:mode><VAXfp:mode>2"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
 	(float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (float:VAXfp (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*float<VAXint:mode><VAXfp:mode>2<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
+	(float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0")
 
 ;; Float-to-fix conversion insns.
 
-(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2"
+(define_insn_and_split "fix_trunc<VAXfp:mode><VAXint:mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
 	(fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (fix:VAXint (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*fix_trunc<VAXfp:mode><VAXint:mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+	(fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0")
 
 (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
@@ -340,21 +700,51 @@ (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
 \f
 ;;- All kinds of add instructions.
 
-(define_insn "add<mode>3"
+(define_insn_and_split "add<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
 	(plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
 		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:VAXfp (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*add<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
+	(plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
+		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    add<VAXfp:fsfx>2 %2,%0
    add<VAXfp:fsfx>2 %1,%0
    add<VAXfp:fsfx>3 %1,%2,%0")
 
-(define_insn "add<mode>3"
+(define_insn_and_split "add<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
 	(plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
 		     (match_operand:VAXint 2 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:VAXint (match_dup 1)
+			(match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*add<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+	(plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
+		     (match_operand:VAXint 2 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_add (insn, operands, <MODE>mode);")
 
 (define_expand "adddi3"
@@ -364,37 +754,109 @@ (define_expand "adddi3"
   "!reload_in_progress"
   "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
 
-(define_insn "adcdi3"
+(define_insn_and_split "adcdi3"
   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
 	(plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
 		 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
   "TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:DI (match_dup 1)
+		    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*adcdi3<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
+	(plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
+		 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "TARGET_QMATH && reload_completed"
   "* return vax_output_int_add (insn, operands, DImode);")
 
 ;; The add-with-carry (adwc) instruction only accepts two operands.
-(define_insn "adddi3_old"
+(define_insn_and_split "adddi3_old"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
 	(plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
 		 (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
   "!TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:DI (match_dup 1)
+		    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*adddi3_old<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
+	(plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
+		 (match_operand:DI 2 "general_operand" "Fsro,Fs")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_QMATH && reload_completed"
   "* return vax_output_int_add (insn, operands, DImode);")
 \f
 ;;- All kinds of subtract instructions.
 
-(define_insn "sub<mode>3"
+(define_insn_and_split "sub<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
 	(minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
 		     (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (minus:VAXfp (match_dup 1)
+			(match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sub<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+	(minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
+		     (match_operand:VAXfp 2 "general_operand" "gF,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    sub<VAXfp:fsfx>2 %2,%0
    sub<VAXfp:fsfx>3 %2,%1,%0")
 
-(define_insn "sub<mode>3"
+(define_insn_and_split "sub<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
 	(minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
 		      (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (minus:VAXint (match_dup 1)
+			 (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sub<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+		      (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "@
+   sub<VAXint:isfx>2 %2,%0
+   sub<VAXint:isfx>3 %2,%1,%0")
+
+(define_insn "*sub<mode>3_cc"
+  [(set (reg:CC VAX_PSL_REGNUM)
+	(compare:CC (match_operand:VAXint 1 "general_operand" "0,nrmT")
+		    (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(minus:VAXint (match_dup 1)
+		      (match_dup 2)))]
+  "reload_completed"
   "@
    sub<VAXint:isfx>2 %2,%0
    sub<VAXint:isfx>3 %2,%1,%0")
@@ -406,52 +868,129 @@ (define_expand "subdi3"
   "!reload_in_progress"
   "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
 
-(define_insn "sbcdi3"
+(define_insn_and_split "sbcdi3"
   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
 	(minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
 		  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
   "TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (minus:DI (match_dup 1)
+		     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sbcdi3<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
+	(minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
+		  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "TARGET_QMATH && reload_completed"
   "* return vax_output_int_subtract (insn, operands, DImode);")
 
 ;; The subtract-with-carry (sbwc) instruction only takes two operands.
-(define_insn "subdi3_old"
+(define_insn_and_split "subdi3_old"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
 	(minus:DI (match_operand:DI 1 "general_operand" "0,or>")
 		  (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
   "!TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (minus:DI (match_dup 1)
+		     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*subdi3_old<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
+	(minus:DI (match_operand:DI 1 "general_operand" "0,or>")
+		  (match_operand:DI 2 "general_operand" "Fsor,Fs")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_QMATH && reload_completed"
   "* return vax_output_int_subtract (insn, operands, DImode);")
 \f
 ;;- Multiply instructions.
 
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
 	(mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
 		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (mult:VAXfp (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mul<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
+	(mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
+		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    mul<VAXfp:fsfx>2 %2,%0
    mul<VAXfp:fsfx>2 %1,%0
    mul<VAXfp:fsfx>3 %1,%2,%0")
 
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
 	(mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
 		     (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (mult:VAXint (match_dup 1)
+			(match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mul<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+	(mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+		     (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    mul<VAXint:isfx>2 %2,%0
    mul<VAXint:isfx>2 %1,%0
    mul<VAXint:isfx>3 %1,%2,%0")
 
-(define_insn "mulsidi3"
+(define_insn_and_split "mulsidi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(mult:DI
 	  (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
 	  (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (mult:DI
+	     (sign_extend:DI (match_dup 1))
+	     (sign_extend:DI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mulsidi3<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(mult:DI
+	  (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	  (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "emul %1,%2,$0,%0")
 
-(define_insn "*maddsidi4"
+(define_insn_and_split "*maddsidi4"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(plus:DI
 	  (mult:DI
@@ -459,10 +998,31 @@ (define_insn "*maddsidi4"
 	    (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
 	  (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:DI
+	     (mult:DI
+	       (sign_extend:DI (match_dup 1))
+	       (sign_extend:DI (match_dup 2)))
+	     (sign_extend:DI (match_dup 3))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*maddsidi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(plus:DI
+	  (mult:DI
+	    (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	    (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+	  (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "emul %1,%2,%3,%0")
 
 ;; 'F' constraint means type CONST_DOUBLE
-(define_insn "*maddsidi4_const"
+(define_insn_and_split "*maddsidi4_const"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(plus:DI
 	  (mult:DI
@@ -471,6 +1031,29 @@ (define_insn "*maddsidi4_const"
 	  (match_operand:DI 3 "immediate_operand" "F")))]
   "GET_CODE (operands[3]) == CONST_DOUBLE
    && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:DI
+	     (mult:DI
+	       (sign_extend:DI (match_dup 1))
+	       (sign_extend:DI (match_dup 2)))
+	     (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*maddsidi4_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(plus:DI
+	  (mult:DI
+	    (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+	    (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+	  (match_operand:DI 3 "immediate_operand" "F")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "GET_CODE (operands[3]) == CONST_DOUBLE
+   && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)
+   && reload_completed"
   "*
 {
   if (CONST_DOUBLE_HIGH (operands[3]))
@@ -480,27 +1063,57 @@ (define_insn "*maddsidi4_const"
 \f
 ;;- Divide instructions.
 
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
 	(div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
 		   (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (div:VAXfp (match_dup 1)
+		      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*div<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+	(div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
+		   (match_operand:VAXfp 2 "general_operand" "gF,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    div<VAXfp:fsfx>2 %2,%0
    div<VAXfp:fsfx>3 %2,%1,%0")
 
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
 	(div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
 		    (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (div:VAXint (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*div<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+		    (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    div<VAXint:isfx>2 %2,%0
    div<VAXint:isfx>3 %2,%1,%0")
 
 ;; This is left out because it is very slow;
 ;; we are better off programming around the "lack" of this insn.
-;;(define_insn "divmoddisi4"
+;;(define_insn_and_split "divmoddisi4"
 ;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;;	(div:SI (match_operand:DI 1 "general_operand" "g")
 ;;		(match_operand:SI 2 "general_operand" "g")))
@@ -508,6 +1121,27 @@ (define_insn "div<mode>3"
 ;;	(mod:SI (match_dup 1)
 ;;		(match_dup 2)))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;	   (div:SI (match_dup 1)
+;;		   (match_dup 2)))
+;;      (set (match_dup 3)
+;;	   (mod:SI (match_dup 1)
+;;		   (match_dup 2)))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*divmoddisi4<ccn><ccnz><ccz>"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;	(div:SI (match_operand:DI 1 "general_operand" "g")
+;;		(match_operand:SI 2 "general_operand" "g")))
+;;   (set (match_operand:SI 3 "nonimmediate_operand" "=g")
+;;	(mod:SI (match_dup 1)
+;;		(match_dup 2)))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "ediv %2,%1,%0,%3")
 \f
 ;; Bit-and on the VAX is done with a clear-bits insn.
@@ -534,11 +1168,29 @@ (define_expand "and<mode>3"
     operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
 }")
 
-(define_insn "*and<mode>"
+(define_insn_and_split "*and<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
-	(and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
+	(and:VAXint (not:VAXint
+		      (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
 		    (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (and:VAXint (not:VAXint
+			 (match_dup 1))
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*and<mode>3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(and:VAXint (not:VAXint
+		      (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
+		    (match_operand:VAXint 2 "general_operand" "0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bic<VAXint:isfx>2 %1,%0
    bic<VAXint:isfx>3 %1,%2,%0")
@@ -548,23 +1200,80 @@ (define_insn "*and<mode>"
 ;; longer a problem.  However, having these patterns allows optimization
 ;; opportunities in combine.c.
 
-(define_insn "*and<mode>_const_int"
+(define_insn_and_split "*and<mode>3_const_int"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
 	(and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
 		    (match_operand:VAXint 2 "const_int_operand" "n,n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (and:VAXint (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*and<mode>3_2_const_int<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+		    (match_operand:VAXint 2 "const_int_operand" "n,n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0
    bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0")
 
+;; We have no direct AND operation and consequently the RTL sequence
+;; the "and<mode>3" pattern produces does not match the instruction
+;; the "*bit<mode>" pattern does for the purpose of the compare
+;; elimination pass.  Try to get rid of the extra operation by hand
+;; and where the sequence is used to set the condition codes only
+;; convert MNEG/BIC => BIT.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:VAXint 0 "register_operand")
+	   (not:VAXint (match_operand:VAXint 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (parallel
+     [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	   (compare:VAXccnz
+	     (and:VAXint (not:VAXint (match_dup 0))
+			 (match_operand:VAXint 3 "general_operand"))
+	     (const_int 0)))
+      (set (match_operand:VAXint 2 "register_operand")
+	   (and:VAXint (not:VAXint (match_dup 0))
+		       (match_dup 3)))])]
+  "peep2_reg_dead_p (2, operands[0]) && peep2_reg_dead_p (2, operands[2])"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz
+	  (and:VAXint (match_dup 1)
+		      (match_dup 3))
+	  (const_int 0)))]
+  "")
 \f
 ;;- Bit set instructions.
 
-(define_insn "ior<mode>3"
+(define_insn_and_split "ior<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
 	(ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
 		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ior:VAXint (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ior<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+	(ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bis<VAXint:isfx>2 %2,%0
    bis<VAXint:isfx>2 %1,%0
@@ -572,35 +1281,97 @@ (define_insn "ior<mode>3"
 
 ;;- xor instructions.
 
-(define_insn "xor<mode>3"
+(define_insn_and_split "xor<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
 	(xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
 		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (xor:VAXint (match_dup 1)
+		       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*xor<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+	(xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    xor<VAXint:isfx>2 %2,%0
    xor<VAXint:isfx>2 %1,%0
    xor<VAXint:isfx>3 %2,%1,%0")
-
 \f
-(define_insn "neg<mode>2"
+(define_insn_and_split "neg<mode>2"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
 	(neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (neg:VAXfp (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*neg<mode>2<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
+	(neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mneg<VAXfp:fsfx> %1,%0")
 
-(define_insn "neg<mode>2"
+(define_insn_and_split "neg<mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
 	(neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (neg:VAXint (match_dup 1)))
+	 (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*neg<mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+	(neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "mneg<VAXint:isfx> %1,%0")
+
+(define_insn "*neg<mode>2_cc"
+  [(set (reg:CC VAX_PSL_REGNUM)
+	(compare:CC (const_int 0)
+		    (neg:VAXint
+		      (match_operand:VAXint 1 "general_operand" "0,nrmT"))))
+   (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+	(neg:VAXint (match_dup 1)))]
+  "reload_completed"
   "mneg<VAXint:isfx> %1,%0")
 
-(define_insn "one_cmpl<mode>2"
+(define_insn_and_split "one_cmpl<mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
 	(not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
   ""
-  "mcom<VAXint:isfx> %1,%0")
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (not:VAXint (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
 
+(define_insn "*one_cmpl<mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+	(not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "mcom<VAXint:isfx> %1,%0")
 \f
 ;; Arithmetic right shift on the VAX works by negating the shift count,
 ;; then emitting a right shift with the shift count negated.  This means
@@ -618,25 +1389,70 @@ (define_expand "ashrsi3"
     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegsi3_const_int"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
 		     (match_operand:QI 2 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ashiftrt:SI (match_dup 1)
+			(match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegsi3_const_int_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+		     (match_operand:QI 2 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashl $%n2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ashiftrt:SI (match_dup 1)
+			(neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegsi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashl %2,%1,%0")
 
-(define_insn "ashlsi3"
+(define_insn_and_split "ashlsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
 		   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ashift:SI (match_dup 1)
+		      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlsi3<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
+		   (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
@@ -673,18 +1489,48 @@ (define_expand "ashrdi3"
   operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn "ashldi3"
+(define_insn_and_split "ashldi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(ashift:DI (match_operand:DI 1 "general_operand" "g")
 		   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ashift:DI (match_dup 1)
+		      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashldi3<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(ashift:DI (match_operand:DI 1 "general_operand" "g")
+		   (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashq %2,%D1,%0")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegdi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (ashiftrt:DI (match_dup 1)
+			(neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegdi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+	(ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
+		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashq %2,%D1,%0")
 
 ;; We used to have expand_shift handle logical right shifts by using extzv,
@@ -719,34 +1565,96 @@ (define_expand "rotrsi3"
     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn "rotlsi3"
+(define_insn_and_split "rotlsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
 		   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (rotate:SI (match_dup 1)
+		      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotlsi3<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
+		   (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*rotrsi3_const_int"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
 		     (match_operand:QI 2 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (rotatert:SI (match_dup 1)
+			(match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotrsi3_const_int_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
+		     (match_operand:QI 2 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %R2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*rotrnegsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (rotatert:SI (match_dup 1)
+			(neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotrnegsi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
+		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %2,%1,%0")
 
 ;; This insn is probably slower than a multiply and an add.
-;;(define_insn "*amulsi4"
+;;(define_insn_and_split "*amulsi4"
 ;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
 ;;			  (match_operand:SI 2 "general_operand" "g"))
 ;;		 (match_operand:SI 3 "general_operand" "g")))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;	   (mult:SI (plus:SI (match_dup 1)
+;;			     (match_dup 2))
+;;		    (match_dup 3)))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*amulsi4_2<ccn><ccnz><ccz>"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
+;;			  (match_operand:SI 2 "general_operand" "g"))
+;;		 (match_operand:SI 3 "general_operand" "g")))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
 \f
 ;; Special cases of bit-field insns which we should
@@ -754,7 +1662,7 @@ (define_insn ""
 ;; These handle aligned 8-bit and 16-bit fields
 ;; that can be done with move or convert instructions.
 
-(define_insn "*insv_aligned"
+(define_insn_and_split "*insv_aligned"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
 			 (match_operand:QI 1 "const_int_operand" "n")
 			 (match_operand:SI 2 "const_int_operand" "n"))
@@ -770,6 +1678,34 @@ (define_insn "*insv_aligned"
    && (!(REG_P (operands[0])
 	 || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
        || INTVAL (operands[2]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (zero_extract:SI (match_dup 0)
+			    (match_dup 1)
+			    (match_dup 2))
+	   (match_dup 3))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*insv_aligned_2<ccn><ccnz><ccz>"
+  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
+			 (match_operand:QI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(match_operand:SI 3 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
+   && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
+   && (!MEM_P (operands[0])
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[0], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[0], 0),
+					 MEM_ADDR_SPACE (operands[0]))))
+   && (!(REG_P (operands[0])
+	 || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
+       || INTVAL (operands[2]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[0]))
@@ -780,13 +1716,12 @@ (define_insn "*insv_aligned"
   else
     gcc_assert (INTVAL (operands[2]) == 0);
 
-  CC_STATUS_INIT;
   if (INTVAL (operands[1]) == 8)
     return \"movb %3,%0\";
   return \"movw %3,%0\";
 }")
 
-(define_insn "*extzv_aligned"
+(define_insn_and_split "*extzv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
 	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "const_int_operand" "n")
@@ -802,6 +1737,34 @@ (define_insn "*extzv_aligned"
    && (!(REG_P (operands[1])
 	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_aligned_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
+	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+			 (match_operand:QI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
+   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
+   && (!MEM_P (operands[1])
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[1], 0),
+					 MEM_ADDR_SPACE (operands[1]))))
+   && (!(REG_P (operands[1])
+	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[1]))
@@ -817,7 +1780,7 @@ (define_insn "*extzv_aligned"
   return \"movzwl %1,%0\";
 }")
 
-(define_insn "*extv_aligned"
+(define_insn_and_split "*extv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "const_int_operand" "n")
@@ -833,6 +1796,34 @@ (define_insn "*extv_aligned"
    && (!(REG_P (operands[1])
 	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_aligned_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+			 (match_operand:QI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
+   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
+   && (!MEM_P (operands[1])
+       || ((!flag_pic
+	    || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+					     true, true))
+	   && !mode_dependent_address_p (XEXP (operands[1], 0),
+					 MEM_ADDR_SPACE (operands[1]))))
+   && (!(REG_P (operands[1])
+	 || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[1]))
@@ -850,24 +1841,24 @@ (define_insn "*extv_aligned"
 \f
 ;; Register and non-offsettable-memory SImode cases of bit-field insns.
 
-(define_insn "*cmpv"
-  [(set (cc0)
-	(compare
+(define_insn "*cmpv_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc
 	 (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpv %2,%1,%0,%3")
 
-(define_insn "*cmpzv"
-  [(set (cc0)
-	(compare
+(define_insn "*cmpzv_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc
 	 (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpzv %2,%1,%0,%3")
 
 ;; When the field position and size are constant and the destination
@@ -875,12 +1866,29 @@ (define_insn "*cmpzv"
 ;; by a bicl or sign extension.  Because we might end up choosing ext[z]v
 ;; anyway, we can't allow immediate values for the primary source operand.
 
-(define_insn "*extv_non_const"
+(define_insn_and_split "*extv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_non_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+			 (match_operand:QI 2 "general_operand" "g")
+			 (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
@@ -892,12 +1900,29 @@ (define_insn "*extv_non_const"
   return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
 }")
 
-(define_insn "*extzv_non_const"
+(define_insn_and_split "*extzv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_non_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+			 (match_operand:QI 2 "general_operand" "g")
+			 (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
@@ -918,24 +1943,24 @@ (define_insn "*extzv_non_const"
 ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
 ;; don't match these (and therefore match the cases above instead).
 
-(define_insn "*cmpv_2"
-  [(set (cc0)
-	(compare
+(define_insn "*cmpv_2_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc
 	 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpv %2,%1,%0,%3")
 
-(define_insn "*cmpzv_2"
-  [(set (cc0)
-	(compare
+(define_insn "*cmpzv_2_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc
 	 (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
 			  (match_operand:QI 1 "general_operand" "g")
 			  (match_operand:SI 2 "general_operand" "nrmT"))
 	 (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpzv %2,%1,%0,%3")
 
 (define_expand "extv"
@@ -946,12 +1971,29 @@ (define_expand "extv"
   ""
   "")
 
-(define_insn "*extv"
+(define_insn_and_split "*extv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (sign_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
+			 (match_operand:QI 2 "general_operand" "g")
+			 (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
@@ -976,12 +2018,29 @@ (define_expand "extzv"
   ""
   "")
 
-(define_insn "*extzv"
+(define_insn_and_split "*extzv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
 			 (match_operand:QI 2 "general_operand" "g")
 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (zero_extract:SI (match_dup 1)
+			    (match_dup 2)
+			    (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
+			 (match_operand:QI 2 "general_operand" "g")
+			 (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
@@ -1021,6 +2080,28 @@ (define_insn "*extzv"
   return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
 }")
 
+;; Combine EXTV/CMPL and EXTZV/CMPL sequences where the output of
+;; extraction is used for the comparison only into CMPV and CMPZV
+;; respectively.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+	   (any_extract:SI (match_operand 1 "general_operand")
+			   (match_operand:QI 2 "general_operand")
+			   (match_operand:SI 3 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc (match_dup 0)
+		       (match_operand:SI 4 "general_operand")))]
+  "peep2_reg_dead_p (2, operands[0])"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc
+	  (any_extract:SI (match_dup 1)
+			  (match_dup 2)
+			  (match_dup 3))
+	  (match_dup 4)))]
+  "")
+
 (define_expand "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
 			 (match_operand:QI 1 "general_operand" "")
@@ -1029,6 +2110,7 @@ (define_expand "insv"
   ""
   "")
 
+;; This one actually doesn't change CC.
 (define_insn "*insv"
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
 			 (match_operand:QI 1 "general_operand" "g")
@@ -1060,6 +2142,7 @@ (define_insn "*insv"
   return \"insv %3,%2,%1,%0\";
 }")
 
+;; This one actually doesn't change CC.
 (define_insn "*insv_2"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
 			 (match_operand:QI 1 "general_operand" "g")
@@ -1078,48 +2161,88 @@ (define_insn "jump"
 ;; Conditional jumps
 
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-        (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
-                 (match_operand:VAXint 2 "general_operand" "")))
+  [(set (pc)
+	(if_then_else
+	  (match_operator 0 "ordered_comparison_operator"
+			  [(match_operand:VAXint 1 "general_operand" "")
+			   (match_operand:VAXint 2 "general_operand" "")])
+	  (label_ref (match_operand 3 "" ""))
+	  (pc)))]
+  ""
+  "")
+
+(define_insn_and_split "*cbranch<VAXint:mode>4_<VAXcc:mode>"
+  [(set (pc)
+	(if_then_else
+	  (match_operator 0 "vax_<cc>_comparison_operator"
+			  [(match_operand:VAXint 1 "general_operand" "nrmT")
+			   (match_operand:VAXint 2 "general_operand" "nrmT")])
+	  (label_ref (match_operand 3 "" ""))
+	  (pc)))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc (match_dup 1) (match_dup 2)))
    (set (pc)
-        (if_then_else
-              (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                               (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
-              (pc)))]
- "")
+	(if_then_else
+	  (match_op_dup 0 [(reg:VAXcc VAX_PSL_REGNUM)
+			   (const_int 0)])
+	 (label_ref (match_operand 3 "" ""))
+	 (pc)))]
+  "")
 
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-        (compare (match_operand:VAXfp 1 "general_operand" "")
-                 (match_operand:VAXfp 2 "general_operand" "")))
+  [(set (pc)
+	(if_then_else
+	  (match_operator 0 "ordered_comparison_operator"
+			  [(match_operand:VAXfp 1 "general_operand" "")
+			   (match_operand:VAXfp 2 "general_operand" "")])
+	  (label_ref (match_operand 3 "" ""))
+	  (pc)))]
+  ""
+  "")
+
+(define_insn_and_split "*cbranch<VAXfp:mode>4_<VAXccnz:mode>"
+  [(set (pc)
+	(if_then_else
+	  (match_operator 0 "vax_<cc>_comparison_operator"
+			  [(match_operand:VAXfp 1 "general_operand" "gF")
+			   (match_operand:VAXfp 2 "general_operand" "gF")])
+	  (label_ref (match_operand 3 "" ""))
+	  (pc)))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+	(compare:VAXccnz (match_dup 1) (match_dup 2)))
    (set (pc)
-        (if_then_else
-              (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                               (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
-              (pc)))]
- "")
-
-(define_insn "*branch"
+	(if_then_else
+ 	  (match_op_dup 0 [(reg:VAXccnz VAX_PSL_REGNUM)
+			   (const_int 0)])
+	  (label_ref (match_operand 3 "" ""))
+	  (pc)))]
+  "")
+
+(define_insn "*branch_<mode>"
   [(set (pc)
-	(if_then_else (match_operator 0 "ordered_comparison_operator"
-				      [(cc0)
+	(if_then_else (match_operator 0 "vax_<cc>_comparison_operator"
+				      [(reg:VAXcc VAX_PSL_REGNUM)
 				       (const_int 0)])
 		      (label_ref (match_operand 1 "" ""))
 		      (pc)))]
-  ""
+  "reload_completed"
   "j%k0 %l1")
 
 ;; Recognize reversed jumps.
-(define_insn "*branch_reversed"
+(define_insn "*branch_<mode>_reversed"
   [(set (pc)
-	(if_then_else (match_operator 0 "ordered_comparison_operator"
-				      [(cc0)
+	(if_then_else (match_operator 0 "vax_<cc>_comparison_operator"
+				      [(reg:VAXcc VAX_PSL_REGNUM)
 				       (const_int 0)])
 		      (pc)
 		      (label_ref (match_operand 1 "" ""))))]
-  ""
+  "reload_completed"
   "j%K0 %l1") ; %K0 negates condition
 \f
 ;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
@@ -1189,7 +2312,7 @@ (define_insn ""
 
 ;; Normal sob insns.
 
-(define_insn ""
+(define_insn_and_split "*jsobgtr"
   [(set (pc)
 	(if_then_else
 	 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1201,9 +2324,38 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int -1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (gt (plus:SI (match_dup 0)
+			 (const_int -1))
+		(const_int 0))
+	    (label_ref (match_dup 1))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobgtr_2"
+  [(set (pc)
+	(if_then_else
+	 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+		      (const_int -1))
+	     (const_int 0))
+	 (label_ref (match_operand 1 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jsobgtr %0,%l1")
 
-(define_insn ""
+(define_insn_and_split "*jsobgeq"
   [(set (pc)
 	(if_then_else
 	 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1215,10 +2367,39 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int -1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (ge (plus:SI (match_dup 0)
+			 (const_int -1))
+		(const_int 0))
+	    (label_ref (match_dup 1))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobgeq_2"
+  [(set (pc)
+	(if_then_else
+	 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+		      (const_int -1))
+	     (const_int 0))
+	 (label_ref (match_operand 1 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jsobgeq %0,%l1")
 
 ;; Normal aob insns.  Define a version for when operands[1] is a constant.
-(define_insn ""
+(define_insn_and_split "*jaoblss"
   [(set (pc)
 	(if_then_else
 	 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1230,9 +2411,38 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int 1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (lt (plus:SI (match_dup 0)
+			 (const_int 1))
+		(match_dup 1))
+	    (label_ref (match_dup 2))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaoblss_2"
+  [(set (pc)
+	(if_then_else
+	 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+		      (const_int 1))
+	     (match_operand:SI 1 "general_operand" "nrmT"))
+	 (label_ref (match_operand 2 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jaoblss %1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaoblss_const"
   [(set (pc)
 	(if_then_else
 	 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1243,9 +2453,36 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int 1)))]
   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (lt (match_dup 0)
+		(match_dup 1))
+	    (label_ref (match_dup 2))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaoblss_const_2"
+  [(set (pc)
+	(if_then_else
+	 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
+	     (match_operand:SI 1 "general_operand" "nrmT"))
+	 (label_ref (match_operand 2 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed"
   "jaoblss %P1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaobleq"
   [(set (pc)
 	(if_then_else
 	 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1257,9 +2494,38 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int 1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (le (plus:SI (match_dup 0)
+			 (const_int 1))
+		(match_dup 1))
+	    (label_ref (match_dup 2))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaobleq_2"
+  [(set (pc)
+	(if_then_else
+	 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+		      (const_int 1))
+	     (match_operand:SI 1 "general_operand" "nrmT"))
+	 (label_ref (match_operand 2 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jaobleq %1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaobleq_const"
   [(set (pc)
 	(if_then_else
 	 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1270,12 +2536,39 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int 1)))]
   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (le (match_dup 0)
+		(match_dup 1))
+	    (label_ref (match_dup 2))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaobleq_const_2"
+  [(set (pc)
+	(if_then_else
+	 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
+	     (match_operand:SI 1 "general_operand" "nrmT"))
+	 (label_ref (match_operand 2 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed"
   "jaobleq %P1,%0,%l2")
 
 ;; Something like a sob insn, but compares against -1.
 ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
 
-(define_insn ""
+(define_insn_and_split "*jsobneq_minus_one"
   [(set (pc)
 	(if_then_else
 	 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
@@ -1286,6 +2579,33 @@ (define_insn ""
 	(plus:SI (match_dup 0)
 		 (const_int -1)))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (pc)
+	   (if_then_else
+	    (ne (match_dup 0)
+		(const_int 0))
+	    (label_ref (match_dup 1))
+	    (pc)))
+      (set (match_dup 0)
+	   (plus:SI (match_dup 0)
+		    (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobneq_minus_one_2"
+  [(set (pc)
+	(if_then_else
+	 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
+	     (const_int 0))
+	 (label_ref (match_operand 1 "" ""))
+	 (pc)))
+   (set (match_dup 0)
+	(plus:SI (match_dup 0)
+		 (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "decl %0\;jgequ %l1")
 \f
 (define_expand "call_pop"
@@ -1512,41 +2832,126 @@ (define_expand "casesi"
 ;; This insn is a bit of a lier.  It actually falls through if no case
 ;; matches.  But, we prevent that from ever happening by emitting a jump
 ;; before this, see the define_expand above.
-(define_insn "casesi1"
+(define_insn_and_split "casesi1"
   [(match_operand:SI 1 "const_int_operand" "n")
    (set (pc)
 	(plus:SI (sign_extend:SI
-		  (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
-					    (const_int 2))
-			  (pc))))
+		   (mem:HI (plus:SI
+			     (mult:SI
+			       (match_operand:SI 0 "general_operand" "nrmT")
+			       (const_int 2))
+			     (pc))))
 		 (label_ref:SI (match_operand 2 "" ""))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(match_dup 1)
+      (set (pc)
+	   (plus:SI (sign_extend:SI
+		      (mem:HI (plus:SI
+				(mult:SI
+				  (match_dup 0)
+				  (const_int 2))
+				(pc))))
+		    (label_ref:SI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*casesi1"
+  [(match_operand:SI 1 "const_int_operand" "n")
+   (set (pc)
+	(plus:SI (sign_extend:SI
+		   (mem:HI (plus:SI
+			     (mult:SI
+			       (match_operand:SI 0 "general_operand" "nrmT")
+			       (const_int 2))
+			     (pc))))
+		 (label_ref:SI (match_operand 2 "" ""))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "casel %0,$0,%1")
 \f
-(define_insn "*pushsym"
+(define_insn_and_split "*pushsym"
   [(set (match_operand:SI 0 "push_operand" "=g")
 	(match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushsym_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+	(match_operand:SI 1 "pic_symbolic_operand" "A"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pushab %a1")
 
-(define_insn "*movsym"
+(define_insn_and_split "*movsym"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsym_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(match_operand:SI 1 "pic_symbolic_operand" "A"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movab %a1,%0")
 
-(define_insn "*pushsymreg"
+(define_insn_and_split "*pushsymreg"
   [(set (match_operand:SI 0 "push_operand" "=g")
 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
 		 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
   "flag_pic"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:SI (match_dup 1)
+		    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushsymreg_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+	(plus:SI (match_operand:SI 1 "register_operand" "%r")
+		 (match_operand:SI 2 "pic_symbolic_operand" "A")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "flag_pic && reload_completed"
   "pushab %a2[%1]")
 
-(define_insn "*movsymreg"
+(define_insn_and_split "*movsymreg"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
 		 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
   "flag_pic"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (plus:SI (match_dup 1)
+		    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsymreg_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(plus:SI (match_operand:SI 1 "register_operand" "%r")
+		 (match_operand:SI 2 "pic_symbolic_operand" "A")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "flag_pic && reload_completed"
   "movab %a2[%1],%0")
 \f
 ;;- load or push effective address
@@ -1557,28 +2962,80 @@ (define_insn "*movsymreg"
 ;; It does not work to use constraints to distinguish pushes from moves,
 ;; because < matches any autodecrement, not just a push.
 
-(define_insn "pushaddr<mode>"
+(define_insn_and_split "pushaddr<mode>"
   [(set (match_operand:SI 0 "push_operand" "=g")
 	(match_operand:VAXintQHSD 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+	(match_operand:VAXintQHSD 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pusha<VAXintQHSD:isfx> %a1")
 
-(define_insn "movaddr<mode>"
+(define_insn_and_split "movaddr<mode>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(match_operand:VAXintQHSD 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(match_operand:VAXintQHSD 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mova<VAXintQHSD:isfx> %a1,%0")
 
-(define_insn "pushaddr<mode>"
+(define_insn_and_split "pushaddr<mode>"
   [(set (match_operand:SI 0 "push_operand" "=g")
 	(match_operand:VAXfp 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+	(match_operand:VAXfp 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pusha<VAXfp:fsfx> %a1")
 
-(define_insn "movaddr<mode>"
+(define_insn_and_split "movaddr<mode>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(match_operand:VAXfp 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movaddr<mode>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+	(match_operand:VAXfp 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mova<VAXfp:fsfx> %a1,%0")
 \f
 ;; These used to be peepholes, but it is more straightforward to do them
@@ -1594,12 +3051,30 @@ (define_insn "movaddr<mode>"
 ;; with other operands constant.  This is what the combiner converts the
 ;; above sequences to before attempting to recognize the new insn.
 
-(define_insn ""
+(define_insn_and_split "*andashlnegsi4"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
 	(and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
 			     (match_operand:QI 2 "const_int_operand" "n"))
 		(match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (and:SI (ashiftrt:SI (match_dup 1)
+				(match_dup 2))
+		   (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*andashlnegsi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
+	(and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+			     (match_operand:QI 2 "const_int_operand" "n"))
+		(match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0
+   && reload_completed"
   "*
 {
   unsigned long mask1 = INTVAL (operands[3]);
@@ -1616,12 +3091,29 @@ (define_insn ""
 ;; bits that the ashl would anyways, in which case it should have been
 ;; optimized away.
 
-(define_insn ""
+(define_insn_and_split "*andashlsi4"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
 	(and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
 			   (match_operand:QI 2 "const_int_operand" "n"))
 		(match_operand:SI 3 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+	   (and:SI (ashift:SI (match_dup 1)
+			      (match_dup 2))
+		   (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*andashlsi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
+	(and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
+			   (match_operand:QI 2 "const_int_operand" "n"))
+		(match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   operands[3]
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 31/31] PR target/95294: VAX: Add test cases for MODE_CC representation
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (29 preceding siblings ...)
  2020-11-20  3:36 ` [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation Maciej W. Rozycki
@ 2020-11-20  3:37 ` Maciej W. Rozycki
  2020-11-21  4:08   ` Jeff Law
  2020-11-20  7:58 ` [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Anders Magnusson
                   ` (3 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

	gcc/testsuite/
	PR target/95294
	* gcc.target/vax/cmpelim-eq-adddf.c: New test.
	* gcc.target/vax/cmpelim-eq-addhi.c: New test.
	* gcc.target/vax/cmpelim-eq-addqi.c: New test.
	* gcc.target/vax/cmpelim-eq-addsf.c: New test.
	* gcc.target/vax/cmpelim-eq-addsi.c: New test.
	* gcc.target/vax/cmpelim-eq-andhi.c: New test.
	* gcc.target/vax/cmpelim-eq-andqi.c: New test.
	* gcc.target/vax/cmpelim-eq-andsi.c: New test.
	* gcc.target/vax/cmpelim-eq-ashlsi.c: New test.
	* gcc.target/vax/cmpelim-eq-ashrsi.c: New test.
	* gcc.target/vax/cmpelim-eq-divdf.c: New test.
	* gcc.target/vax/cmpelim-eq-divhi.c: New test.
	* gcc.target/vax/cmpelim-eq-divqi.c: New test.
	* gcc.target/vax/cmpelim-eq-divsf.c: New test.
	* gcc.target/vax/cmpelim-eq-divsi.c: New test.
	* gcc.target/vax/cmpelim-eq-extendhisi.c: New test.
	* gcc.target/vax/cmpelim-eq-extendqisi.c: New test.
	* gcc.target/vax/cmpelim-eq-extvsi.c: New test.
	* gcc.target/vax/cmpelim-eq-extzvsi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixdfhi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixdfqi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixdfsi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixsfhi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixsfqi.c: New test.
	* gcc.target/vax/cmpelim-eq-fixsfsi.c: New test.
	* gcc.target/vax/cmpelim-eq-floatsisf.c: New test.
	* gcc.target/vax/cmpelim-eq-insvsi.c: New test.
	* gcc.target/vax/cmpelim-eq-iorhi.c: New test.
	* gcc.target/vax/cmpelim-eq-iorqi.c: New test.
	* gcc.target/vax/cmpelim-eq-iorsi.c: New test.
	* gcc.target/vax/cmpelim-eq-mova.c: New test.
	* gcc.target/vax/cmpelim-eq-movdf.c: New test.
	* gcc.target/vax/cmpelim-eq-movhi.c: New test.
	* gcc.target/vax/cmpelim-eq-movqi.c: New test.
	* gcc.target/vax/cmpelim-eq-movsf.c: New test.
	* gcc.target/vax/cmpelim-eq-movsi.c: New test.
	* gcc.target/vax/cmpelim-eq-muldf.c: New test.
	* gcc.target/vax/cmpelim-eq-mulhi.c: New test.
	* gcc.target/vax/cmpelim-eq-mulqi.c: New test.
	* gcc.target/vax/cmpelim-eq-mulsf.c: New test.
	* gcc.target/vax/cmpelim-eq-mulsi.c: New test.
	* gcc.target/vax/cmpelim-eq-nothi.c: New test.
	* gcc.target/vax/cmpelim-eq-notqi.c: New test.
	* gcc.target/vax/cmpelim-eq-notsi.c: New test.
	* gcc.target/vax/cmpelim-eq-rotlsi.c: New test.
	* gcc.target/vax/cmpelim-eq-rotrsi.c: New test.
	* gcc.target/vax/cmpelim-eq-subdf.c: New test.
	* gcc.target/vax/cmpelim-eq-subhi.c: New test.
	* gcc.target/vax/cmpelim-eq-subqi.c: New test.
	* gcc.target/vax/cmpelim-eq-subsf.c: New test.
	* gcc.target/vax/cmpelim-eq-subsi.c: New test.
	* gcc.target/vax/cmpelim-eq-truncdfsf.c: New test.
	* gcc.target/vax/cmpelim-eq-trunchiqi.c: New test.
	* gcc.target/vax/cmpelim-eq-truncsihi.c: New test.
	* gcc.target/vax/cmpelim-eq-truncsiqi.c: New test.
	* gcc.target/vax/cmpelim-eq-zextendhisi.c: New test.
	* gcc.target/vax/cmpelim-eq-zextendqihi.c: New test.
	* gcc.target/vax/cmpelim-eq-zextendqisi.c: New test.
	* gcc.target/vax/cmpelim-le-adddf.c: New test.
	* gcc.target/vax/cmpelim-le-addhi.c: New test.
	* gcc.target/vax/cmpelim-le-addqi.c: New test.
	* gcc.target/vax/cmpelim-le-addsf.c: New test.
	* gcc.target/vax/cmpelim-le-addsi.c: New test.
	* gcc.target/vax/cmpelim-le-andhi.c: New test.
	* gcc.target/vax/cmpelim-le-andqi.c: New test.
	* gcc.target/vax/cmpelim-le-andsi.c: New test.
	* gcc.target/vax/cmpelim-le-ashlsi.c: New test.
	* gcc.target/vax/cmpelim-le-ashrsi.c: New test.
	* gcc.target/vax/cmpelim-le-divdf.c: New test.
	* gcc.target/vax/cmpelim-le-divhi.c: New test.
	* gcc.target/vax/cmpelim-le-divqi.c: New test.
	* gcc.target/vax/cmpelim-le-divsf.c: New test.
	* gcc.target/vax/cmpelim-le-divsi.c: New test.
	* gcc.target/vax/cmpelim-le-extendhisi.c: New test.
	* gcc.target/vax/cmpelim-le-extendqisi.c: New test.
	* gcc.target/vax/cmpelim-le-extvsi.c: New test.
	* gcc.target/vax/cmpelim-le-extzvsi.c: New test.
	* gcc.target/vax/cmpelim-le-fixdfhi.c: New test.
	* gcc.target/vax/cmpelim-le-fixdfqi.c: New test.
	* gcc.target/vax/cmpelim-le-fixdfsi.c: New test.
	* gcc.target/vax/cmpelim-le-fixsfhi.c: New test.
	* gcc.target/vax/cmpelim-le-fixsfqi.c: New test.
	* gcc.target/vax/cmpelim-le-fixsfsi.c: New test.
	* gcc.target/vax/cmpelim-le-floatsisf.c: New test.
	* gcc.target/vax/cmpelim-le-insvsi.c: New test.
	* gcc.target/vax/cmpelim-le-iorhi.c: New test.
	* gcc.target/vax/cmpelim-le-iorqi.c: New test.
	* gcc.target/vax/cmpelim-le-iorsi.c: New test.
	* gcc.target/vax/cmpelim-le-movdf.c: New test.
	* gcc.target/vax/cmpelim-le-movhi.c: New test.
	* gcc.target/vax/cmpelim-le-movqi.c: New test.
	* gcc.target/vax/cmpelim-le-movsf.c: New test.
	* gcc.target/vax/cmpelim-le-movsi.c: New test.
	* gcc.target/vax/cmpelim-le-muldf.c: New test.
	* gcc.target/vax/cmpelim-le-mulhi.c: New test.
	* gcc.target/vax/cmpelim-le-mulqi.c: New test.
	* gcc.target/vax/cmpelim-le-mulsf.c: New test.
	* gcc.target/vax/cmpelim-le-mulsi.c: New test.
	* gcc.target/vax/cmpelim-le-nothi.c: New test.
	* gcc.target/vax/cmpelim-le-notqi.c: New test.
	* gcc.target/vax/cmpelim-le-notsi.c: New test.
	* gcc.target/vax/cmpelim-le-rotlsi.c: New test.
	* gcc.target/vax/cmpelim-le-rotrsi.c: New test.
	* gcc.target/vax/cmpelim-le-subdf.c: New test.
	* gcc.target/vax/cmpelim-le-subhi.c: New test.
	* gcc.target/vax/cmpelim-le-subqi.c: New test.
	* gcc.target/vax/cmpelim-le-subsf.c: New test.
	* gcc.target/vax/cmpelim-le-subsi.c: New test.
	* gcc.target/vax/cmpelim-le-truncdfsf.c: New test.
	* gcc.target/vax/cmpelim-le-xorhi.c: New test.
	* gcc.target/vax/cmpelim-le-xorqi.c: New test.
	* gcc.target/vax/cmpelim-le-xorsi.c: New test.
	* gcc.target/vax/cmpelim-leu-subhi.c: New test.
	* gcc.target/vax/cmpelim-leu-subqi.c: New test.
	* gcc.target/vax/cmpelim-leu-subsi.c: New test.
	* gcc.target/vax/cmpelim-lt-adddf.c: New test.
	* gcc.target/vax/cmpelim-lt-addhi.c: New test.
	* gcc.target/vax/cmpelim-lt-addqi.c: New test.
	* gcc.target/vax/cmpelim-lt-addsf.c: New test.
	* gcc.target/vax/cmpelim-lt-addsi.c: New test.
	* gcc.target/vax/cmpelim-lt-andhi.c: New test.
	* gcc.target/vax/cmpelim-lt-andqi.c: New test.
	* gcc.target/vax/cmpelim-lt-andsi.c: New test.
	* gcc.target/vax/cmpelim-lt-ashlsi.c: New test.
	* gcc.target/vax/cmpelim-lt-ashrsi.c: New test.
	* gcc.target/vax/cmpelim-lt-divdf.c: New test.
	* gcc.target/vax/cmpelim-lt-divhi.c: New test.
	* gcc.target/vax/cmpelim-lt-divqi.c: New test.
	* gcc.target/vax/cmpelim-lt-divsf.c: New test.
	* gcc.target/vax/cmpelim-lt-divsi.c: New test.
	* gcc.target/vax/cmpelim-lt-extendhisi.c: New test.
	* gcc.target/vax/cmpelim-lt-extendqisi.c: New test.
	* gcc.target/vax/cmpelim-lt-extvsi.c: New test.
	* gcc.target/vax/cmpelim-lt-extzvsi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixdfhi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixdfqi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixdfsi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixsfhi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixsfqi.c: New test.
	* gcc.target/vax/cmpelim-lt-fixsfsi.c: New test.
	* gcc.target/vax/cmpelim-lt-floatsisf.c: New test.
	* gcc.target/vax/cmpelim-lt-insvsi.c: New test.
	* gcc.target/vax/cmpelim-lt-iorhi.c: New test.
	* gcc.target/vax/cmpelim-lt-iorqi.c: New test.
	* gcc.target/vax/cmpelim-lt-iorsi.c: New test.
	* gcc.target/vax/cmpelim-lt-movdf.c: New test.
	* gcc.target/vax/cmpelim-lt-movhi.c: New test.
	* gcc.target/vax/cmpelim-lt-movqi.c: New test.
	* gcc.target/vax/cmpelim-lt-movsf.c: New test.
	* gcc.target/vax/cmpelim-lt-movsi.c: New test.
	* gcc.target/vax/cmpelim-lt-muldf.c: New test.
	* gcc.target/vax/cmpelim-lt-mulhi.c: New test.
	* gcc.target/vax/cmpelim-lt-mulqi.c: New test.
	* gcc.target/vax/cmpelim-lt-mulsf.c: New test.
	* gcc.target/vax/cmpelim-lt-mulsi.c: New test.
	* gcc.target/vax/cmpelim-lt-nothi.c: New test.
	* gcc.target/vax/cmpelim-lt-notqi.c: New test.
	* gcc.target/vax/cmpelim-lt-notsi.c: New test.
	* gcc.target/vax/cmpelim-lt-rotlsi.c: New test.
	* gcc.target/vax/cmpelim-lt-rotrsi.c: New test.
	* gcc.target/vax/cmpelim-lt-subdf.c: New test.
	* gcc.target/vax/cmpelim-lt-subhi.c: New test.
	* gcc.target/vax/cmpelim-lt-subqi.c: New test.
	* gcc.target/vax/cmpelim-lt-subsf.c: New test.
	* gcc.target/vax/cmpelim-lt-subsi.c: New test.
	* gcc.target/vax/cmpelim-lt-truncdfsf.c: New test.
	* gcc.target/vax/cmpelim-lt-xorhi.c: New test.
	* gcc.target/vax/cmpelim-lt-xorqi.c: New test.
	* gcc.target/vax/cmpelim-lt-xorsi.c: New test.
	* gcc.target/vax/cmpelim-ltu-subhi.c: New test.
	* gcc.target/vax/cmpelim-ltu-subqi.c: New test.
	* gcc.target/vax/cmpelim-ltu-subsi.c: New test.
	* gcc.target/vax/cmpelim-xx-addsi.c: New test.
	* gcc.target/vax/cmpelim-xx-insvsi.c: New test.
	* gcc.target/vax/cmpelim-xxu-subsi.c: New test.
	* gcc.target/vax/peephole2-eq-andhi.c: New test.
	* gcc.target/vax/peephole2-eq-andqi.c: New test.
	* gcc.target/vax/peephole2-eq-andsi.c: New test.
	* gcc.target/vax/peephole2-eq-cmpvsi.c: New test.
	* gcc.target/vax/peephole2-eq-cmpzvsi.c: New test.
	* gcc.target/vax/peephole2-eq-ctzhi-0.c: New test.
	* gcc.target/vax/peephole2-eq-ctzhi-1.c: New test.
	* gcc.target/vax/peephole2-eq-ctzqi-0.c: New test.
	* gcc.target/vax/peephole2-eq-ctzqi-1.c: New test.
	* gcc.target/vax/peephole2-eq-ctzsi-0.c: New test.
	* gcc.target/vax/peephole2-eq-ctzsi-1.c: New test.
	* gcc.target/vax/peephole2-eq-ffshi.c: New test.
	* gcc.target/vax/peephole2-eq-ffsqi.c: New test.
	* gcc.target/vax/peephole2-eq-ffssi.c: New test.
	* gcc.target/vax/peephole2-le-andhi.c: New test.
	* gcc.target/vax/peephole2-le-andqi.c: New test.
	* gcc.target/vax/peephole2-le-andsi.c: New test.
	* gcc.target/vax/peephole2-le-cmpvsi.c: New test.
	* gcc.target/vax/peephole2-le-cmpzvsi.c: New test.
	* gcc.target/vax/peephole2-leu-cmpvsi.c: New test.
	* gcc.target/vax/peephole2-leu-cmpzvsi.c: New test.
	* gcc.target/vax/peephole2-lt-andhi.c: New test.
	* gcc.target/vax/peephole2-lt-andqi.c: New test.
	* gcc.target/vax/peephole2-lt-andsi.c: New test.
	* gcc.target/vax/peephole2-lt-cmpvsi.c: New test.
	* gcc.target/vax/peephole2-lt-cmpzvsi.c: New test.
	* gcc.target/vax/peephole2-ltu-cmpvsi.c: New test.
	* gcc.target/vax/peephole2-ltu-cmpzvsi.c: New test.
---
 gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c   | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c   | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-eq-extendhisi.c         | 30 ++++++++++++
 .../gcc.target/vax/cmpelim-eq-extendqisi.c         | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c   | 38 ++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c  | 39 ++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c  | 32 +++++++++++++
 .../gcc.target/vax/cmpelim-eq-floatsisf.c          | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c   | 46 +++++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c     | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c   | 34 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-eq-truncdfsf.c          | 32 +++++++++++++
 .../gcc.target/vax/cmpelim-eq-trunchiqi.c          | 33 ++++++++++++++
 .../gcc.target/vax/cmpelim-eq-truncsihi.c          | 33 ++++++++++++++
 .../gcc.target/vax/cmpelim-eq-truncsiqi.c          | 33 ++++++++++++++
 .../gcc.target/vax/cmpelim-eq-zextendhisi.c        | 30 ++++++++++++
 .../gcc.target/vax/cmpelim-eq-zextendqihi.c        | 32 +++++++++++++
 .../gcc.target/vax/cmpelim-eq-zextendqisi.c        | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c   | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c   | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-le-extendhisi.c         | 30 ++++++++++++
 .../gcc.target/vax/cmpelim-le-extendqisi.c         | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c   | 38 ++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c  | 32 +++++++++++++
 .../gcc.target/vax/cmpelim-le-floatsisf.c          | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c   | 46 +++++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c   | 34 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-le-truncdfsf.c          | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c   | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c   | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-lt-extendhisi.c         | 30 ++++++++++++
 .../gcc.target/vax/cmpelim-lt-extendqisi.c         | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c   | 38 ++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c  | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c  | 32 +++++++++++++
 .../gcc.target/vax/cmpelim-lt-floatsisf.c          | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c   | 46 +++++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c    | 28 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c   | 34 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c    | 29 ++++++++++++
 .../gcc.target/vax/cmpelim-lt-truncdfsf.c          | 32 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c    | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c    | 29 ++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c   | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c    | 36 +++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c   | 53 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c   | 40 ++++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c  | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c | 36 +++++++++++++++
 .../gcc.target/vax/peephole2-eq-cmpzvsi.c          | 36 +++++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzhi-0.c          | 32 +++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzhi-1.c          | 34 ++++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzqi-0.c          | 32 +++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzqi-1.c          | 34 ++++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzsi-0.c          | 32 +++++++++++++
 .../gcc.target/vax/peephole2-eq-ctzsi-1.c          | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c  | 26 +++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c  | 26 +++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c  | 27 +++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c  | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c | 36 +++++++++++++++
 .../gcc.target/vax/peephole2-le-cmpzvsi.c          | 34 ++++++++++++++
 .../gcc.target/vax/peephole2-leu-cmpvsi.c          | 40 ++++++++++++++++
 .../gcc.target/vax/peephole2-leu-cmpzvsi.c         | 31 +++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c  | 33 ++++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c  | 30 ++++++++++++
 gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c | 36 +++++++++++++++
 .../gcc.target/vax/peephole2-lt-cmpzvsi.c          | 34 ++++++++++++++
 .../gcc.target/vax/peephole2-ltu-cmpvsi.c          | 40 ++++++++++++++++
 .../gcc.target/vax/peephole2-ltu-cmpzvsi.c         | 31 +++++++++++++
 203 files changed, 6382 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c
 create mode 100644 gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c

diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c
new file mode 100644
index 00000000000..872d46bbd76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-adddf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+eq_adddf (float_t x, float_t y)
+{
+  x += y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addd3 4(%ap),12(%ap),%r0	# 35	[c=68]  *adddf3_ccz/2
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addd2 $0d2.0e+0,%r0		# 34	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "adddf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c
new file mode 100644
index 00000000000..3a5dbad72dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_addhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addw3 *8(%ap),*12(%ap),%r0	# 33	[c=64]  *addhi3_ccz
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 32	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c
new file mode 100644
index 00000000000..b0fe468ee65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_addqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addb3 *8(%ap),*12(%ap),%r0	# 33	[c=64]  *addqi3_ccz
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 32	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c
new file mode 100644
index 00000000000..de9e9c1b9d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+eq_addsf (float_t x, float_t y)
+{
+  x += y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addf3 4(%ap),8(%ap),%r0		# 34	[c=48]  *addsf3_ccz/2
+	jeql .L1			# 36	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 33	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c
new file mode 100644
index 00000000000..6998e606a07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-addsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_addsi (int_t x, int_t y)
+{
+  x += y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),8(%ap),%r0		# 33	[c=48]  *addsi3_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c
new file mode 100644
index 00000000000..d4d0c59d2b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicw3 *12(%ap),*8(%ap),%r0	# 34	[c=44]  *andhi3_2_ccz/1
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 33	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c
new file mode 100644
index 00000000000..efa0dfe95a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicb3 *12(%ap),*8(%ap),%r0	# 34	[c=44]  *andqi3_2_ccz/1
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 33	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c
new file mode 100644
index 00000000000..9afc86090a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-andsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_andsi (int_t x, int_t y)
+{
+  x &= ~y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bicl3 8(%ap),4(%ap),%r0		# 35	[c=28]  *andsi3_2_ccz/1
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 34	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c
new file mode 100644
index 00000000000..a824f2d1987
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashlsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+eq_ashlsi (int_t x, short_t y)
+{
+  x <<= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	ashl 8(%ap),4(%ap),%r0		# 35	[c=56]  *ashlsi3_ccz
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 34	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c
new file mode 100644
index 00000000000..5f1e3a41919
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-ashrsi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+eq_ashrsi (int_t x, short_t y)
+{
+  x >>= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 36	[c=16]  *negqi2
+	ashl %r0,4(%ap),%r0		# 37	[c=52]  *ashlnegsi3_2_ccz
+	jeql .L1			# 39	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 35	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c
new file mode 100644
index 00000000000..7101960351c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+eq_divdf (float_t x, float_t y)
+{
+  x /= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divd3 12(%ap),4(%ap),%r0	# 35	[c=112]  *divdf3_ccz/1
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addd2 $0d2.0e+0,%r0		# 34	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c
new file mode 100644
index 00000000000..03866f9554f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI), vector_size (2))) int_t;
+
+void
+eq_divhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divw3 *12(%ap),*8(%ap),%r0	# 38	[c=76]  *divhi3_ccz/1
+	jeql .L2			# 40	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 37	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c
new file mode 100644
index 00000000000..e4cfbf0315c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI), vector_size (1))) int_t;
+
+void
+eq_divqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divb3 *12(%ap),*8(%ap),%r0	# 38	[c=76]  *divqi3_ccz/1
+	jeql .L2			# 40	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 37	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c
new file mode 100644
index 00000000000..492becfd080
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+eq_divsf (float_t x, float_t y)
+{
+  x /= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divf3 8(%ap),4(%ap),%r0		# 34	[c=60]  *divsf3_ccz/1
+	jeql .L1			# 36	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 33	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c
new file mode 100644
index 00000000000..324614fdbd3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-divsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_divsi (int_t x, int_t y)
+{
+  x /= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divl3 8(%ap),4(%ap),%r0		# 33	[c=60]  *divsi3_ccz/1
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c
new file mode 100644
index 00000000000..f875da9202c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendhisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (HI))) short_t;
+
+int_t
+eq_extendhisi (int_t x)
+{
+  x = (short_t) x;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtwl 4(%ap),%r0		# 33	[c=20]  *extendhisi2_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c
new file mode 100644
index 00000000000..16a6acd8098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extendqisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+eq_extendqisi (int_t x)
+{
+  x = (short_t) x;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtbl 4(%ap),%r0		# 33	[c=20]  *extendqisi2_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c
new file mode 100644
index 00000000000..5383059fe01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extvsi.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+eq_extvsi (bit_t x)
+{
+  int_t v;
+
+  v = x.i;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	extv $7,$18,4(%ap),%r0		# 32	[c=68]  *extv_non_const_2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c
new file mode 100644
index 00000000000..d21fa293936
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-extzvsi.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+eq_extzvsi (bit_t x)
+{
+  int_t v;
+
+  v = x.i;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	rotl $25,4(%ap),%r0		# 32	[c=68]  *extzv_non_const_2_ccz
+	bicl2 $-262144,%r0
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extzv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c
new file mode 100644
index 00000000000..8912d14b31a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_fixdfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdw 8(%ap),%r0		# 31	[c=36]  *fix_truncdfhi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 30	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c
new file mode 100644
index 00000000000..12f9385bba2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_fixdfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdb 8(%ap),%r0		# 31	[c=36]  *fix_truncdfqi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 30	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c
new file mode 100644
index 00000000000..ad54d88b9ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixdfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_fixdfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdl 4(%ap),%r0		# 32	[c=36]  *fix_truncdfsi2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c
new file mode 100644
index 00000000000..0c26857c014
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_fixsfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfw 8(%ap),%r0		# 31	[c=36]  *fix_truncsfhi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 30	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c
new file mode 100644
index 00000000000..2d32525bc29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_fixsfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfb 8(%ap),%r0		# 31	[c=36]  *fix_truncsfqi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 30	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c
new file mode 100644
index 00000000000..a704ad8600a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-fixsfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_fixsfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfl 4(%ap),%r0		# 32	[c=36]  *fix_truncsfsi2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c
new file mode 100644
index 00000000000..1ea83cc8ef7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-floatsisf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+float_t
+eq_floatsisf (int_t x)
+{
+  float_t v;
+
+  v = x;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtlf 4(%ap),%r0		# 33	[c=32]  *floatsisf2_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 32	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c
new file mode 100644
index 00000000000..fbdcdb43b06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-insvsi.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef union
+  {
+    int_t i;
+    struct
+      {
+	int_t h : 7;
+	int_t i : 18;
+	int_t l : 7;
+      } b;
+  }
+bit_t;
+
+int
+eq_insvsi (bit_t x, int_t y)
+{
+  int_t v;
+
+  v = x.b.i;
+  x.b.i = y;
+  if (v != 0)
+    return x.i;
+  else
+    return x.i + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 35	[c=16]  *movsi_2
+	extv $7,$18,%r0,%r1		# 36	[c=60]  *extv_non_const_2_ccz
+	insv 8(%ap),$7,$18,%r0		# 8	[c=16]  *insv_2
+	jneq .L1			# 38	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 34	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "extv.*insv.*branch" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c
new file mode 100644
index 00000000000..9bbe881897e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_iorhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisw3 *12(%ap),*8(%ap),%r0	# 32	[c=44]  *iorhi3_ccz/2
+	jeql .L2			# 34	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 31	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c
new file mode 100644
index 00000000000..82f3f6bb7c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_iorqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisb3 *12(%ap),*8(%ap),%r0	# 32	[c=44]  *iorqi3_ccz/2
+	jeql .L2			# 34	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 31	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c
new file mode 100644
index 00000000000..dd4490d9fd2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-iorsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_iorsi (int_t x, int_t y)
+{
+  x |= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bisl3 8(%ap),4(%ap),%r0		# 33	[c=28]  *iorsi3_ccz/2
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c
new file mode 100644
index 00000000000..286025f4982
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mova.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+extern char __attribute__ ((weak)) c;
+
+char *
+eq_mova (char *p)
+{
+  char *v;
+
+  v = &c;
+  if (v)
+    return v;
+  return p;
+}
+
+/* Expect assembly like:
+
+	movab c,%r0			# 35	[c=12]  *movsym_2_ccz
+	jeql .L6			# 37	[c=26]  *branch_ccz
+	ret				# 43	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsym\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c
new file mode 100644
index 00000000000..c83e966c889
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+eq_movdf (float_t x)
+{
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movd 4(%ap),%r0			# 34	[c=24]  *movdf_ccz/1
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addd2 $0d2.0e+0,%r0		# 33	[c=56]  *adddf3/0
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c
new file mode 100644
index 00000000000..99832dcf74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_movhi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r0		# 31	[c=24]  *movhi_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 30	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c
new file mode 100644
index 00000000000..5014b8bcbc6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_movqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r0		# 31	[c=24]  *movqi_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 30	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c
new file mode 100644
index 00000000000..89074613d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+eq_movsf (float_t x)
+{
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movf 4(%ap),%r0			# 33	[c=16]  *movsf_ccz/1
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 32	[c=36]  *addsf3/0
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c
new file mode 100644
index 00000000000..1e65f4b81f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-movsi.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_movsi (int_t x)
+{
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 32	[c=16]  *movsi_2_ccz
+	jeql .L2			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c
new file mode 100644
index 00000000000..7271c218d33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-muldf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+eq_muldf (float_t x, float_t y)
+{
+  x *= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	muld3 4(%ap),12(%ap),%r0	# 35	[c=80]  *muldf3_ccz/2
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addd2 $0d2.0e+0,%r0		# 34	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "muldf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c
new file mode 100644
index 00000000000..d44a62250d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_mulhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulw3 *8(%ap),*12(%ap),%r0	# 33	[c=72]  *mulhi3_ccz/2
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 32	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c
new file mode 100644
index 00000000000..2451843e704
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_mulqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulb3 *8(%ap),*12(%ap),%r0	# 33	[c=72]  *mulqi3_ccz/2
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 32	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c
new file mode 100644
index 00000000000..824487bf488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+eq_mulsf (float_t x, float_t y)
+{
+  x *= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mulf3 4(%ap),8(%ap),%r0		# 34	[c=52]  *mulsf3_ccz/2
+	jeql .L1			# 36	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 33	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c
new file mode 100644
index 00000000000..fbefa541784
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-mulsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_mulsi (int_t x, int_t y)
+{
+  x *= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mull3 4(%ap),8(%ap),%r0		# 33	[c=56]  *mulsi3_ccz/2
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c
new file mode 100644
index 00000000000..79b274c7841
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-nothi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_nothi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomw *8(%ap),%r0		# 31	[c=24]  *one_cmplhi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 30	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c
new file mode 100644
index 00000000000..ae98a2fbc7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_notqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomb *8(%ap),%r0		# 31	[c=24]  *one_cmplqi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 30	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c
new file mode 100644
index 00000000000..ba5b735e01b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-notsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_notsi (int_t x)
+{
+  x = ~x;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mcoml 4(%ap),%r0		# 32	[c=16]  *one_cmplsi2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c
new file mode 100644
index 00000000000..17c48687299
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotlsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+eq_rotlsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x << y | x >> 8 * sizeof (x) - y;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	rotl 8(%ap),4(%ap),%r0		# 36	[c=40]  *rotlsi3_ccz
+	jeql .L1			# 38	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 35	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c
new file mode 100644
index 00000000000..ffbca234867
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-rotrsi.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+eq_rotrsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x >> y | x << 8 * sizeof (x) - y;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 37	[c=16]  *negqi2
+	rotl %r0,4(%ap),%r0		# 38	[c=36]  *rotrnegsi3_2_ccz
+	jeql .L1			# 40	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 36	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c
new file mode 100644
index 00000000000..a8d3f1f93a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+eq_subdf (float_t x, float_t y)
+{
+  x -= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subd3 12(%ap),4(%ap),%r0	# 35	[c=68]  *subdf3_ccz/1
+	jeql .L1			# 37	[c=26]  *branch_ccz
+	addd2 $0d2.0e+0,%r0		# 34	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subdf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c
new file mode 100644
index 00000000000..f01b4b6f968
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_subhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subw3 *12(%ap),*8(%ap),%r0	# 33	[c=64]  *subhi3_ccz/1
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 32	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c
new file mode 100644
index 00000000000..733e30f8b05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_subqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subb3 *12(%ap),*8(%ap),%r0	# 33	[c=64]  *subqi3_ccz/1
+	jeql .L2			# 35	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 32	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c
new file mode 100644
index 00000000000..34e8555ca19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+eq_subsf (float_t x, float_t y)
+{
+  x -= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subf3 8(%ap),4(%ap),%r0		# 34	[c=48]  *subsf3_ccz/1
+	jeql .L1			# 36	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 33	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c
new file mode 100644
index 00000000000..456e35a737e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-subsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_subsi (int_t x, int_t y)
+{
+  x -= y;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subl3 8(%ap),4(%ap),%r0		# 33	[c=48]  *subsi3_ccz/1
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c
new file mode 100644
index 00000000000..7192d874aef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncdfsf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) single_t;
+typedef float __attribute__ ((mode (DF))) double_t;
+
+single_t
+eq_truncdfsf (double_t x)
+{
+  single_t v;
+
+  v = x;
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdf 4(%ap),%r0		# 33	[c=20]  *truncdfsf2_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addf2 $0f2.0e+0,%r0		# 32	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c
new file mode 100644
index 00000000000..9e7a8850eae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-trunchiqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (HI))) int_t;
+typedef unsigned int __attribute__ ((mode (QI))) short_t;
+
+void
+eq_trunchiqi (short_t *w, int_t *x, int y)
+{
+  short_t v;
+
+  v = x[y];
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 12(%ap),%r0		# 33	[c=16]  *movsi_2
+	cvtwb *8(%ap)[%r0],%r0		# 34	[c=28]  *trunchiqi2_ccz
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 32	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "trunchiqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c
new file mode 100644
index 00000000000..36dd7dfccca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsihi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef unsigned int __attribute__ ((mode (HI))) short_t;
+
+void
+eq_truncsihi (short_t *w, int_t *x, int y)
+{
+  short_t v;
+
+  v = x[y];
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 12(%ap),%r0		# 33	[c=16]  *movsi_2
+	cvtlw *8(%ap)[%r0],%r0		# 34	[c=28]  *truncsihi2_ccz
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 32	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "truncsihi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c
new file mode 100644
index 00000000000..a0ee4cffa7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-truncsiqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef unsigned int __attribute__ ((mode (QI))) short_t;
+
+void
+eq_truncsiqi (short_t *w, int_t *x, int y)
+{
+  short_t v;
+
+  v = x[y];
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 12(%ap),%r0		# 33	[c=16]  *movsi_2
+	cvtlb *8(%ap)[%r0],%r0		# 34	[c=28]  *truncsiqi2_ccz
+	jeql .L2			# 36	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 32	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "truncsiqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c
new file mode 100644
index 00000000000..2fa86dde7b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendhisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef unsigned int __attribute__ ((mode (HI))) short_t;
+
+int_t
+eq_zextendhisi (int_t x)
+{
+  x = (short_t) x;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movzwl 4(%ap),%r0		# 32	[c=20]  *zero_extendhisi2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "zero_extendhisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c
new file mode 100644
index 00000000000..16613c6e16f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqihi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (HI))) int_t;
+typedef unsigned int __attribute__ ((mode (QI))) short_t;
+
+void
+eq_zextendqihi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = (short_t) *x;
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movzbw *8(%ap),%r0		# 31	[c=28]  *zero_extendqihi2_ccz
+	jeql .L2			# 33	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 30	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "zero_extendqihi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c
new file mode 100644
index 00000000000..bb75f73cd68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-eq-zextendqisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef unsigned int __attribute__ ((mode (QI))) short_t;
+
+int_t
+eq_zextendqisi (int_t x)
+{
+  x = (short_t) x;
+  if (x == 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movzbl 4(%ap),%r0		# 32	[c=20]  *zero_extendqisi2_ccz
+	jeql .L1			# 34	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "zero_extendqisi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c
new file mode 100644
index 00000000000..383d51d662c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-adddf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+le_adddf (float_t x, float_t y)
+{
+  x += y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addd3 4(%ap),12(%ap),%r0	# 29	[c=68]  *adddf3_ccnz/2
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "adddf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c
new file mode 100644
index 00000000000..19cc6219110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_addhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addw3 *8(%ap),*12(%ap),%r0	# 29	[c=64]  *addhi3_ccnz
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c
new file mode 100644
index 00000000000..291beb028f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_addqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addb3 *8(%ap),*12(%ap),%r0	# 29	[c=64]  *addqi3_ccnz
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c
new file mode 100644
index 00000000000..e4596fe7c33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+le_addsf (float_t x, float_t y)
+{
+  x += y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addf3 4(%ap),8(%ap),%r0		# 28	[c=48]  *addsf3_ccnz/2
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c
new file mode 100644
index 00000000000..254b30c2ea7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-addsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_addsi (int_t x, int_t y)
+{
+  x += y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),8(%ap),%r0		# 29	[c=48]  *addsi3_ccnz
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c
new file mode 100644
index 00000000000..ddf04d90b6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicw3 *12(%ap),*8(%ap),%r0	# 30	[c=44]  *andhi3_2_ccnz/1
+	jleq .L2			# 32	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 29	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c
new file mode 100644
index 00000000000..bd781dc1ad9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicb3 *12(%ap),*8(%ap),%r0	# 30	[c=44]  *andqi3_2_ccnz/1
+	jleq .L2			# 32	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 29	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c
new file mode 100644
index 00000000000..81fd7ba9a8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-andsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_andsi (int_t x, int_t y)
+{
+  x &= ~y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bicl3 8(%ap),4(%ap),%r0		# 31	[c=28]  *andsi3_2_ccnz/1
+	jleq .L1			# 33	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c
new file mode 100644
index 00000000000..2b677424b26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashlsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+le_ashlsi (int_t x, short_t y)
+{
+  x <<= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	ashl 8(%ap),4(%ap),%r0		# 31	[c=56]  *ashlsi3_ccnz
+	jleq .L1			# 33	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c
new file mode 100644
index 00000000000..c4d9f28d0e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-ashrsi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+le_ashrsi (int_t x, short_t y)
+{
+  x >>= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 32	[c=16]  *negqi2
+	ashl %r0,4(%ap),%r0		# 33	[c=52]  *ashlnegsi3_2_ccnz
+	jleq .L1			# 35	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c
new file mode 100644
index 00000000000..62b419ccd43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+le_divdf (float_t x, float_t y)
+{
+  x /= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divd3 12(%ap),4(%ap),%r0	# 29	[c=112]  *divdf3_ccnz/1
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c
new file mode 100644
index 00000000000..68ee4844fd2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI), vector_size (2))) int_t;
+
+void
+le_divhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divw3 *12(%ap),*8(%ap),%r0	# 34	[c=76]  *divhi3_ccnz/1
+	jleq .L2			# 36	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 33	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c
new file mode 100644
index 00000000000..e0b0cd31754
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI), vector_size (1))) int_t;
+
+void
+le_divqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divb3 *12(%ap),*8(%ap),%r0	# 34	[c=76]  *divqi3_ccnz/1
+	jleq .L2			# 36	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 33	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c
new file mode 100644
index 00000000000..b55b36e622d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+le_divsf (float_t x, float_t y)
+{
+  x /= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divf3 8(%ap),4(%ap),%r0		# 28	[c=60]  *divsf3_ccnz/1
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c
new file mode 100644
index 00000000000..6a45a38c242
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-divsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_divsi (int_t x, int_t y)
+{
+  x /= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divl3 8(%ap),4(%ap),%r0		# 29	[c=60]  *divsi3_ccnz/1
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c
new file mode 100644
index 00000000000..693c752f8aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendhisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (HI))) short_t;
+
+int_t
+le_extendhisi (int_t x)
+{
+  x = (short_t) x;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtwl 4(%ap),%r0		# 29	[c=20]  *extendhisi2_ccnz
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c
new file mode 100644
index 00000000000..4965bcff4d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extendqisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+le_extendqisi (int_t x)
+{
+  x = (short_t) x;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtbl 4(%ap),%r0		# 29	[c=20]  *extendqisi2_ccnz
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c
new file mode 100644
index 00000000000..641c8f0dd3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extvsi.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+le_extvsi (bit_t x)
+{
+  int_t v;
+
+  v = x.i;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	extv $7,$18,4(%ap),%r0		# 28	[c=68]  *extv_non_const_2_ccnz
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c
new file mode 100644
index 00000000000..18dd7ff9bd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-extzvsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+le_extzvsi (uint_t x, int_t y)
+{
+  int_t v;
+
+  v = x >> y;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 31	[c=40]  *subqi3/1
+	extzv 8(%ap),%r0,4(%ap),%r0	# 32	[c=76]  *extzv_non_const_2_ccnz
+	jleq .L1			# 34	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extzv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c
new file mode 100644
index 00000000000..ea649c63c52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_fixdfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdw 8(%ap),%r0		# 27	[c=36]  *fix_truncdfhi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c
new file mode 100644
index 00000000000..a53e9367c04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_fixdfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdb 8(%ap),%r0		# 27	[c=36]  *fix_truncdfqi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c
new file mode 100644
index 00000000000..bcf5f364155
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixdfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_fixdfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdl 4(%ap),%r0		# 28	[c=36]  *fix_truncdfsi2_ccnz
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c
new file mode 100644
index 00000000000..2301500531b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_fixsfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfw 8(%ap),%r0		# 27	[c=36]  *fix_truncsfhi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c
new file mode 100644
index 00000000000..34a47837134
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_fixsfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfb 8(%ap),%r0		# 27	[c=36]  *fix_truncsfqi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c
new file mode 100644
index 00000000000..39735af7e51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-fixsfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_fixsfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfl 4(%ap),%r0		# 28	[c=36]  *fix_truncsfsi2_ccnz
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c
new file mode 100644
index 00000000000..bab7101c3a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-floatsisf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+float_t
+le_floatsisf (int_t x)
+{
+  float_t v;
+
+  v = x;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtlf 4(%ap),%r0		# 27	[c=32]  *floatsisf2_ccnz
+	jleq .L1			# 29	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 26	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c
new file mode 100644
index 00000000000..26c368ba9cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-insvsi.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef union
+  {
+    int_t i;
+    struct
+      {
+	int_t h : 7;
+	int_t i : 18;
+	int_t l : 7;
+      } b;
+  }
+bit_t;
+
+int
+le_insvsi (bit_t x, int_t y)
+{
+  int_t v;
+
+  v = x.b.i;
+  x.b.i = y;
+  if (v <= 0)
+    return x.i;
+  else
+    return x.i + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 37	[c=16]  *movsi_2
+	extv $7,$18,%r0,%r1		# 38	[c=60]  *extv_non_const_2_ccnz
+	insv 8(%ap),$7,$18,%r0		# 8	[c=16]  *insv_2
+	jleq .L1			# 40	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 36	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "extv.*insv.*branch" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c
new file mode 100644
index 00000000000..26a4d765778
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_iorhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisw3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *iorhi3_ccnz/2
+	jleq .L2			# 30	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c
new file mode 100644
index 00000000000..fbb97b33e54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_iorqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisb3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *iorqi3_ccnz/2
+	jleq .L2			# 30	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c
new file mode 100644
index 00000000000..4cf50fe89ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-iorsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_iorsi (int_t x, int_t y)
+{
+  x |= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bisl3 8(%ap),4(%ap),%r0		# 29	[c=28]  *iorsi3_ccnz/2
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c
new file mode 100644
index 00000000000..acbaa2d3a85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movdf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+le_movdf (float_t x)
+{
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movd 4(%ap),%r0			# 34	[c=24]  *movdf_ccnz/1
+	jleq .L1			# 36	[c=26]  *branch_ccnz
+	addd2 $0d2.0e+0,%r0		# 33	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c
new file mode 100644
index 00000000000..3e99f872101
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_movhi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r0		# 27	[c=24]  *movhi_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c
new file mode 100644
index 00000000000..8c73a822240
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_movqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r0		# 27	[c=24]  *movqi_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c
new file mode 100644
index 00000000000..71a70b8e70d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+le_movsf (float_t x)
+{
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movf 4(%ap),%r0			# 33	[c=16]  *movsf_ccnz/1
+	jleq .L1			# 35	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 32	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c
new file mode 100644
index 00000000000..2203f8b1713
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-movsi.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_movsi (int_t x)
+{
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 34	[c=16]  *movsi_2_ccnz
+	jleq .L1			# 36	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 33	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c
new file mode 100644
index 00000000000..ed3193def4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-muldf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+le_muldf (float_t x, float_t y)
+{
+  x *= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	muld3 4(%ap),12(%ap),%r0	# 29	[c=80]  *muldf3_ccnz/2
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "muldf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c
new file mode 100644
index 00000000000..426a469be1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_mulhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulw3 *8(%ap),*12(%ap),%r0	# 29	[c=72]  *mulhi3_ccnz/2
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c
new file mode 100644
index 00000000000..ca3bb48d951
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_mulqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulb3 *8(%ap),*12(%ap),%r0	# 29	[c=72]  *mulqi3_ccnz/2
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c
new file mode 100644
index 00000000000..0d3ac3776d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+le_mulsf (float_t x, float_t y)
+{
+  x *= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mulf3 4(%ap),8(%ap),%r0		# 28	[c=52]  *mulsf3_ccnz/2
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c
new file mode 100644
index 00000000000..de72158569e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-mulsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_mulsi (int_t x, int_t y)
+{
+  x *= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mull3 4(%ap),8(%ap),%r0		# 29	[c=56]  *mulsi3_ccnz/2
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c
new file mode 100644
index 00000000000..6884a782e01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-nothi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_nothi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomw *8(%ap),%r0		# 27	[c=24]  *one_cmplhi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c
new file mode 100644
index 00000000000..60a9e615484
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-notqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_notqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomb *8(%ap),%r0		# 27	[c=24]  *one_cmplqi2_ccnz
+	jleq .L2			# 29	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c
new file mode 100644
index 00000000000..938a6b3a4d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-notsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_notsi (int_t x)
+{
+  x = ~x;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mcoml 4(%ap),%r0		# 28	[c=16]  *one_cmplsi2_ccnz
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c
new file mode 100644
index 00000000000..9e01429cd0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotlsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+le_rotlsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x << y | x >> 8 * sizeof (x) - y;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	rotl 8(%ap),4(%ap),%r0		# 32	[c=40]  *rotlsi3_ccnz
+	jleq .L1			# 34	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c
new file mode 100644
index 00000000000..4fe533bc086
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-rotrsi.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+le_rotrsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x >> y | x << 8 * sizeof (x) - y;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 33	[c=16]  *negqi2
+	rotl %r0,4(%ap),%r0		# 34	[c=36]  *rotrnegsi3_2_ccnz
+	jleq .L1			# 36	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c
new file mode 100644
index 00000000000..0456cd32bb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+le_subdf (float_t x, float_t y)
+{
+  x -= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subd3 12(%ap),4(%ap),%r0	# 29	[c=68]  *subdf3_ccnz/1
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subdf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c
new file mode 100644
index 00000000000..4391b76b7be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_subhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subw3 *12(%ap),*8(%ap),%r0	# 29	[c=64]  *subhi3_ccnz/1
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c
new file mode 100644
index 00000000000..f725be9b809
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_subqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subb3 *12(%ap),*8(%ap),%r0	# 29	[c=64]  *subqi3_ccnz/1
+	jleq .L2			# 31	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c
new file mode 100644
index 00000000000..77a9bf06b11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+le_subsf (float_t x, float_t y)
+{
+  x -= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subf3 8(%ap),4(%ap),%r0		# 28	[c=48]  *subsf3_ccnz/1
+	jleq .L1			# 30	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c
new file mode 100644
index 00000000000..db64ffc5b57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-subsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_subsi (int_t x, int_t y)
+{
+  x -= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subl3 8(%ap),4(%ap),%r0		# 29	[c=48]  *subsi3_ccnz/1
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c
new file mode 100644
index 00000000000..6e7673d607f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-truncdfsf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) single_t;
+typedef float __attribute__ ((mode (DF))) double_t;
+
+single_t
+le_truncdfsf (double_t x)
+{
+  single_t v;
+
+  v = x;
+  if (v <= 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdf 4(%ap),%r0		# 27	[c=20]  *truncdfsf2_ccnz
+	jleq .L1			# 29	[c=26]  *branch_ccnz
+	addf2 $0f2.0e+0,%r0		# 26	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c
new file mode 100644
index 00000000000..e65eed8a4bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_xorhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x ^ *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	xorw3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *xorhi3_ccnz/2
+	jleq .L2			# 30	[c=26]  *branch_ccnz
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorhi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c
new file mode 100644
index 00000000000..ca8d5fb80a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_xorqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x ^ *y;
+  if (v <= 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	xorb3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *xorqi3_ccnz/2
+	jleq .L2			# 30	[c=26]  *branch_ccnz
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c
new file mode 100644
index 00000000000..3de63cabc39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-le-xorsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_xorsi (int_t x, int_t y)
+{
+  x ^= y;
+  if (x <= 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	xorl3 8(%ap),4(%ap),%r0		# 29	[c=28]  *xorsi3_ccnz/2
+	jleq .L1			# 31	[c=26]  *branch_ccnz
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c
new file mode 100644
index 00000000000..5f3e372d5e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subhi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (HI))) int_t;
+
+void
+leu_subhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (*x <= *y)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r2		# 28	[c=24]  *movhi
+	movw *12(%ap),%r1		# 29	[c=24]  *movhi
+	subw3 %r1,%r2,%r0		# 30	[c=32]  *subhi3_cc/1
+	jlequ .L2			# 32	[c=26]  *branch_cc
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subhi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c
new file mode 100644
index 00000000000..97ef2a9836b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (QI))) int_t;
+
+void
+leu_subqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (*x <= *y)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r2		# 28	[c=24]  *movqi
+	movb *12(%ap),%r1		# 29	[c=24]  *movqi
+	subb3 %r1,%r2,%r0		# 30	[c=32]  *subqi3_cc/1
+	jlequ .L2			# 32	[c=26]  *branch_cc
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subqi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c
new file mode 100644
index 00000000000..9402fab0ea2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-leu-subsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+leu_subsi (int_t x, int_t y)
+{
+  int_t v;
+
+  v = x - y;
+  if (x <= y)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r2			# 27	[c=16]  *movsi_2
+	movl 8(%ap),%r1			# 28	[c=16]  *movsi_2
+	subl3 %r1,%r2,%r0		# 29	[c=32]  *subsi3_cc/1
+	jlequ .L1			# 31	[c=26]  *branch_cc
+	addl2 $2,%r0			# 26	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c
new file mode 100644
index 00000000000..6e3718d5e2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-adddf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+lt_adddf (float_t x, float_t y)
+{
+  x += y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addd3 4(%ap),12(%ap),%r0	# 29	[c=68]  *adddf3_ccn/2
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "adddf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c
new file mode 100644
index 00000000000..a93675a500f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_addhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addw3 *8(%ap),*12(%ap),%r0	# 29	[c=64]  *addhi3_ccn
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c
new file mode 100644
index 00000000000..32a1328ae12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_addqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x + *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	addb3 *8(%ap),*12(%ap),%r0	# 29	[c=64]  *addqi3_ccn
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c
new file mode 100644
index 00000000000..19c0b68b5f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+lt_addsf (float_t x, float_t y)
+{
+  x += y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addf3 4(%ap),8(%ap),%r0		# 28	[c=48]  *addsf3_ccn/2
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c
new file mode 100644
index 00000000000..1bb59d358ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-addsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_addsi (int_t x, int_t y)
+{
+  x += y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),8(%ap),%r0		# 29	[c=48]  *addsi3_ccn
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c
new file mode 100644
index 00000000000..f7259311708
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicw3 *12(%ap),*8(%ap),%r0	# 30	[c=44]  *andhi3_2_ccn/1
+	jlss .L2			# 32	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 29	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c
new file mode 100644
index 00000000000..afae63586d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & ~*y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bicb3 *12(%ap),*8(%ap),%r0	# 30	[c=44]  *andqi3_2_ccn/1
+	jlss .L2			# 32	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 29	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c
new file mode 100644
index 00000000000..5a86ddb51b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-andsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_andsi (int_t x, int_t y)
+{
+  x &= ~y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bicl3 8(%ap),4(%ap),%r0		# 31	[c=28]  *andsi3_2_ccn/1
+	jlss .L1			# 33	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "andsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c
new file mode 100644
index 00000000000..0c858936bf8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashlsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+lt_ashlsi (int_t x, short_t y)
+{
+  x <<= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	ashl 8(%ap),4(%ap),%r0		# 31	[c=56]  *ashlsi3_ccn
+	jlss .L1			# 33	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c
new file mode 100644
index 00000000000..977f32cb4fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-ashrsi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+lt_ashrsi (int_t x, short_t y)
+{
+  x >>= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 32	[c=16]  *negqi2
+	ashl %r0,4(%ap),%r0		# 33	[c=52]  *ashlnegsi3_2_ccn
+	jlss .L1			# 35	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ashlnegsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c
new file mode 100644
index 00000000000..ddcb8c1ccd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+lt_divdf (float_t x, float_t y)
+{
+  x /= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divd3 12(%ap),4(%ap),%r0	# 29	[c=112]  *divdf3_ccn/1
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c
new file mode 100644
index 00000000000..23bbf425544
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI), vector_size (2))) int_t;
+
+void
+lt_divhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divw3 *12(%ap),*8(%ap),%r0	# 34	[c=76]  *divhi3_ccn/1
+	jlss .L2			# 36	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 33	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c
new file mode 100644
index 00000000000..5401b6b23e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI), vector_size (1))) int_t;
+
+void
+lt_divqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x / *y;
+  if (v[0] < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	divb3 *12(%ap),*8(%ap),%r0	# 34	[c=76]  *divqi3_ccn/1
+	jlss .L2			# 36	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 33	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c
new file mode 100644
index 00000000000..89d5930bcc5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+lt_divsf (float_t x, float_t y)
+{
+  x /= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divf3 8(%ap),4(%ap),%r0		# 28	[c=60]  *divsf3_ccn/1
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c
new file mode 100644
index 00000000000..5c50635d897
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-divsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_divsi (int_t x, int_t y)
+{
+  x /= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	divl3 8(%ap),4(%ap),%r0		# 29	[c=60]  *divsi3_ccn/1
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "divsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c
new file mode 100644
index 00000000000..5dcc89aad35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendhisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (HI))) short_t;
+
+int_t
+lt_extendhisi (int_t x)
+{
+  x = (short_t) x;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtwl 4(%ap),%r0		# 29	[c=20]  *extendhisi2_ccn
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendhisi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c
new file mode 100644
index 00000000000..9ec5a415bb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extendqisi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+typedef int __attribute__ ((mode (QI))) short_t;
+
+int_t
+lt_extendqisi (int_t x)
+{
+  x = (short_t) x;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	cvtbl 4(%ap),%r0		# 29	[c=20]  *extendqisi2_ccn
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extendqisi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c
new file mode 100644
index 00000000000..a10435ba78c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extvsi.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+lt_extvsi (bit_t x)
+{
+  int_t v;
+
+  v = x.i;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	extv $7,$18,4(%ap),%r0		# 28	[c=68]  *extv_non_const_2_ccn
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c
new file mode 100644
index 00000000000..e019d741193
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-extzvsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+lt_extzvsi (uint_t x, int_t y)
+{
+  int_t v;
+
+  v = x >> y;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 31	[c=40]  *subqi3/1
+	extzv 8(%ap),%r0,4(%ap),%r0	# 32	[c=76]  *extzv_non_const_2_ccn
+	jlss .L1			# 34	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 30	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extzv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c
new file mode 100644
index 00000000000..5d63a22d098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_fixdfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdw 8(%ap),%r0		# 27	[c=36]  *fix_truncdfhi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c
new file mode 100644
index 00000000000..d1616558a18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_fixdfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdb 8(%ap),%r0		# 27	[c=36]  *fix_truncdfqi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c
new file mode 100644
index 00000000000..b07d1dedab6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixdfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_fixdfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdl 4(%ap),%r0		# 28	[c=36]  *fix_truncdfsi2_ccn
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncdfsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c
new file mode 100644
index 00000000000..42c8d74e9c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfhi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_fixsfhi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfw 8(%ap),%r0		# 27	[c=36]  *fix_truncsfhi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c
new file mode 100644
index 00000000000..49327ee7eaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfqi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_fixsfqi (int_t *w, float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfb 8(%ap),%r0		# 27	[c=36]  *fix_truncsfqi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c
new file mode 100644
index 00000000000..3d172910aeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-fixsfsi.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_fixsfsi (float_t x)
+{
+  int_t v;
+
+  v = x;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtfl 4(%ap),%r0		# 28	[c=36]  *fix_truncsfsi2_ccn
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "fix_truncsfsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c
new file mode 100644
index 00000000000..cefc71ef908
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-floatsisf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+float_t
+lt_floatsisf (int_t x)
+{
+  float_t v;
+
+  v = x;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtlf 4(%ap),%r0		# 27	[c=32]  *floatsisf2_ccn
+	jlss .L1			# 29	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 26	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "floatsisf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c
new file mode 100644
index 00000000000..52f97ef4559
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-insvsi.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef union
+  {
+    int_t i;
+    struct
+      {
+	int_t h : 7;
+	int_t i : 18;
+	int_t l : 7;
+      } b;
+  }
+bit_t;
+
+int
+lt_insvsi (bit_t x, int_t y)
+{
+  int_t v;
+
+  v = x.b.i;
+  x.b.i = y;
+  if (v < 0)
+    return x.i;
+  else
+    return x.i + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 37	[c=16]  *movsi_2
+	extv $7,$18,%r0,%r1		# 38	[c=60]  *extv_non_const_2_ccn
+	insv 8(%ap),$7,$18,%r0		# 8	[c=16]  *insv_2
+	jlss .L1			# 40	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 36	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "extv.*insv.*branch" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c
new file mode 100644
index 00000000000..edd91e1d791
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_iorhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisw3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *iorhi3_ccn/2
+	jlss .L2			# 30	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c
new file mode 100644
index 00000000000..82a9e04e59a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_iorqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x | *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	bisb3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *iorqi3_ccn/2
+	jlss .L2			# 30	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c
new file mode 100644
index 00000000000..12466868312
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-iorsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_iorsi (int_t x, int_t y)
+{
+  x |= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	bisl3 8(%ap),4(%ap),%r0		# 29	[c=28]  *iorsi3_ccn/2
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "iorsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c
new file mode 100644
index 00000000000..02b4c5abf84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movdf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+lt_movdf (float_t x)
+{
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movd 4(%ap),%r0			# 34	[c=24]  *movdf_ccn/1
+	jlss .L1			# 36	[c=26]  *branch_ccn
+	addd2 $0d2.0e+0,%r0		# 33	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c
new file mode 100644
index 00000000000..51ce5b7eace
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_movhi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r0		# 27	[c=24]  *movhi_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c
new file mode 100644
index 00000000000..fb5450cc63f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_movqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = *x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r0		# 27	[c=24]  *movqi_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c
new file mode 100644
index 00000000000..1669f16209d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsf.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+lt_movsf (float_t x)
+{
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movf 4(%ap),%r0			# 33	[c=16]  *movsf_ccn/1
+	jlss .L1			# 35	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 32	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c
new file mode 100644
index 00000000000..b4cd073352b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-movsi.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_movsi (int_t x)
+{
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 34	[c=16]  *movsi_2_ccn
+	jlss .L1			# 36	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 33	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "movsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c
new file mode 100644
index 00000000000..1f9279ba662
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-muldf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+lt_muldf (float_t x, float_t y)
+{
+  x *= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	muld3 4(%ap),12(%ap),%r0	# 29	[c=80]  *muldf3_ccn/2
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "muldf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c
new file mode 100644
index 00000000000..29a77e39d19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_mulhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulw3 *8(%ap),*12(%ap),%r0	# 29	[c=72]  *mulhi3_ccn/2
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c
new file mode 100644
index 00000000000..844456e60e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_mulqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x * *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mulb3 *8(%ap),*12(%ap),%r0	# 29	[c=72]  *mulqi3_ccn/2
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c
new file mode 100644
index 00000000000..ea1c083f4aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+lt_mulsf (float_t x, float_t y)
+{
+  x *= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mulf3 4(%ap),8(%ap),%r0		# 28	[c=52]  *mulsf3_ccn/2
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c
new file mode 100644
index 00000000000..5f46c8c573b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-mulsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_mulsi (int_t x, int_t y)
+{
+  x *= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mull3 4(%ap),8(%ap),%r0		# 29	[c=56]  *mulsi3_ccn/2
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "mulsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c
new file mode 100644
index 00000000000..59d1d9a5dbf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-nothi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_nothi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomw *8(%ap),%r0		# 27	[c=24]  *one_cmplhi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 26	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c
new file mode 100644
index 00000000000..7a2ef96e77e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_notqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = ~*x;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	mcomb *8(%ap),%r0		# 27	[c=24]  *one_cmplqi2_ccn
+	jlss .L2			# 29	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 26	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c
new file mode 100644
index 00000000000..c3586b198fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-notsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_notsi (int_t x)
+{
+  x = ~x;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	mcoml 4(%ap),%r0		# 28	[c=16]  *one_cmplsi2_ccn
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 27	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "one_cmplsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c
new file mode 100644
index 00000000000..7f5c89d14ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotlsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+lt_rotlsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x << y | x >> 8 * sizeof (x) - y;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	rotl 8(%ap),4(%ap),%r0		# 32	[c=40]  *rotlsi3_ccn
+	jlss .L1			# 34	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotlsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c
new file mode 100644
index 00000000000..6c9daf4b73e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-rotrsi.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) ulong_t;
+typedef int __attribute__ ((mode (SI))) long_t;
+typedef int __attribute__ ((mode (QI))) int_t;
+
+ulong_t
+lt_rotrsi (ulong_t x, int_t y)
+{
+  long_t v;
+
+  v = x >> y | x << 8 * sizeof (x) - y;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	mnegb 8(%ap),%r0		# 33	[c=16]  *negqi2
+	rotl %r0,4(%ap),%r0		# 34	[c=36]  *rotrnegsi3_2_ccn
+	jlss .L1			# 36	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "rotrnegsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c
new file mode 100644
index 00000000000..fb7bb1d2fe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subdf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (DF))) float_t;
+
+float_t
+lt_subdf (float_t x, float_t y)
+{
+  x -= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subd3 12(%ap),4(%ap),%r0	# 29	[c=68]  *subdf3_ccn/1
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addd2 $0d2.0e+0,%r0		# 28	[c=56]  *adddf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subdf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c
new file mode 100644
index 00000000000..d06af83554e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_subhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subw3 *12(%ap),*8(%ap),%r0	# 29	[c=64]  *subhi3_ccn/1
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 28	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c
new file mode 100644
index 00000000000..254ad715e73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_subqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	subb3 *12(%ap),*8(%ap),%r0	# 29	[c=64]  *subqi3_ccn/1
+	jlss .L2			# 31	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 28	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c
new file mode 100644
index 00000000000..26181d80174
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsf.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) float_t;
+
+float_t
+lt_subsf (float_t x, float_t y)
+{
+  x -= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subf3 8(%ap),4(%ap),%r0		# 28	[c=48]  *subsf3_ccn/1
+	jlss .L1			# 30	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 27	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c
new file mode 100644
index 00000000000..6e98e4cbbc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-subsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_subsi (int_t x, int_t y)
+{
+  x -= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	subl3 8(%ap),4(%ap),%r0		# 29	[c=48]  *subsi3_ccn/1
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c
new file mode 100644
index 00000000000..98fac66bd37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-truncdfsf.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef float __attribute__ ((mode (SF))) single_t;
+typedef float __attribute__ ((mode (DF))) double_t;
+
+single_t
+lt_truncdfsf (double_t x)
+{
+  single_t v;
+
+  v = x;
+  if (v < 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtdf 4(%ap),%r0		# 27	[c=20]  *truncdfsf2_ccn
+	jlss .L1			# 29	[c=26]  *branch_ccn
+	addf2 $0f2.0e+0,%r0		# 26	[c=36]  *addsf3/0
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "truncdfsf\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c
new file mode 100644
index 00000000000..be36e0a3334
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorhi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+lt_xorhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x ^ *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	xorw3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *xorhi3_ccn/2
+	jlss .L2			# 30	[c=26]  *branch_ccn
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorhi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c
new file mode 100644
index 00000000000..51b05e711fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorqi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_xorqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x ^ *y;
+  if (v < 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	xorb3 *12(%ap),*8(%ap),%r0	# 28	[c=44]  *xorqi3_ccn/2
+	jlss .L2			# 30	[c=26]  *branch_ccn
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c
new file mode 100644
index 00000000000..439e36d9657
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-lt-xorsi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_xorsi (int_t x, int_t y)
+{
+  x ^= y;
+  if (x < 0)
+    return x;
+  else
+    return x + 2;
+}
+
+/* Expect assembly like:
+
+	xorl3 8(%ap),4(%ap),%r0		# 29	[c=28]  *xorsi3_ccn/2
+	jlss .L1			# 31	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 28	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "xorsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c
new file mode 100644
index 00000000000..7965322d93f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subhi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (HI))) int_t;
+
+void
+ltu_subhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (*x < *y)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r2		# 28	[c=24]  *movhi
+	movw *12(%ap),%r1		# 29	[c=24]  *movhi
+	subw3 %r1,%r2,%r0		# 30	[c=32]  *subhi3_cc/1
+	jlssu .L2			# 32	[c=26]  *branch_cc
+	addw2 $2,%r0			# 27	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subhi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c
new file mode 100644
index 00000000000..3ba1d0f37f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (QI))) int_t;
+
+void
+ltu_subqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x - *y;
+  if (*x < *y)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r2		# 28	[c=24]  *movqi
+	movb *12(%ap),%r1		# 29	[c=24]  *movqi
+	subb3 %r1,%r2,%r0		# 30	[c=32]  *subqi3_cc/1
+	jlssu .L2			# 32	[c=26]  *branch_cc
+	addb2 $2,%r0			# 27	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subqi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c
new file mode 100644
index 00000000000..542ff809a35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-ltu-subsi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+ltu_subsi (int_t x, int_t y)
+{
+  int_t v;
+
+  v = x - y;
+  if (x < y)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r2			# 27	[c=16]  *movsi_2
+	movl 8(%ap),%r1			# 28	[c=16]  *movsi_2
+	subl3 %r1,%r2,%r0		# 29	[c=32]  *subsi3_cc/1
+	jlssu .L1			# 31	[c=26]  *branch_cc
+	addl2 $2,%r0			# 26	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 1 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c
new file mode 100644
index 00000000000..033b1195c1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-xx-addsi.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+xx_addsi (int_t x, int_t y)
+{
+  x += y;
+  if (x == 0)
+    return x;
+  else if (x >= 0)
+    return x + 2;
+  else
+    return x - 3;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),8(%ap),%r0		# 47	[c=48]  *addsi3_ccnz
+	jeql .L1			# 49	[c=26]  *branch_ccz
+	jlss .L3			# 46	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 44	[c=32]  *addsi3
+	ret				# 39	[c=0]  return
+.L3:
+	subl2 $3,%r0			# 43	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "addsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c
new file mode 100644
index 00000000000..8f3e4ff8901
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-xx-insvsi.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef union
+  {
+    int_t i;
+    struct
+      {
+	int_t h : 7;
+	int_t i : 18;
+	int_t l : 7;
+      } b;
+  }
+bit_t;
+
+int
+xx_insvsi (bit_t x, int_t y)
+{
+  int_t v;
+
+  v = x.b.i;
+  x.b.i = y;
+  if (v == 0)
+    return x.i;
+  else if (v >= 0)
+    return x.i + 2;
+  else
+    return x.i - 3;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r0			# 50	[c=16]  *movsi_2
+	extv $7,$18,%r0,%r1		# 51	[c=60]  *extv_non_const_2_ccnz
+	insv 8(%ap),$7,$18,%r0		# 8	[c=16]  *insv_2
+	jeql .L1			# 53	[c=26]  *branch_ccz
+	jlss .L4			# 49	[c=26]  *branch_ccn
+	addl2 $2,%r0			# 47	[c=32]  *addsi3
+	ret				# 42	[c=0]  return
+.L4:
+	subl2 $3,%r0			# 46	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "extv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "extv.*insv.*branch" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c b/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c
new file mode 100644
index 00000000000..b9f730445fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/cmpelim-xxu-subsi.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-cmpelim -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+
+int_t
+xxu_subsi (int_t x, int_t y)
+{
+  int_t v;
+
+  v = x - y;
+  if (x == y)
+    return v;
+  else if (x >= y)
+    return v + 2;
+  else
+    return v - 3;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r2			# 39	[c=16]  *movsi_2
+	movl 8(%ap),%r1			# 40	[c=16]  *movsi_2
+	subl3 %r1,%r2,%r0		# 41	[c=32]  *subsi3_cc/1
+	jeql .L1			# 43	[c=26]  *branch_ccz
+	jlssu .L3			# 38	[c=26]  *branch_cc
+	addl2 $2,%r0			# 36	[c=32]  *addsi3
+	ret				# 31	[c=0]  return
+.L3:
+	subl2 $3,%r0			# 35	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "deleting insn with uid" 2 "cmpelim" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "subsi\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c
new file mode 100644
index 00000000000..485b32497ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andhi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v == 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitw *8(%ap),*12(%ap)		# 50	[c=50]  *bithi_ccz
+	jneq .L3			# 40	[c=26]  *branch_ccz
+	movw $1,%r0			# 36	[c=4]  *movhi
+	movw %r0,*4(%ap)		# 34	[c=4]  *movhi
+	ret				# 46	[c=0]  return
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bithi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c
new file mode 100644
index 00000000000..ffea453b5ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v == 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitb *8(%ap),*12(%ap)		# 50	[c=50]  *bitqi_ccz
+	jneq .L3			# 40	[c=26]  *branch_ccz
+	movb $1,%r0			# 36	[c=4]  *movqi
+	movb %r0,*4(%ap)		# 34	[c=4]  *movqi
+	ret				# 46	[c=0]  return
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c
new file mode 100644
index 00000000000..b84c35299ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-andsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_andsi (int_t x, int_t y)
+{
+  x &= y;
+  if (x == 0)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	bitl 4(%ap),8(%ap)		# 52	[c=34]  *bitsi_ccz
+	jneq .L6			# 41	[c=26]  *branch_ccz
+	movl $1,%r0			# 36	[c=4]  *movsi_2
+	ret				# 47	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c
new file mode 100644
index 00000000000..3e09a78a7e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpvsi.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+eq_cmpvsi (bit_t x, int_t y)
+{
+  if (x.i == y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpv_ccz
+	jeql .L3			# 39	[c=26]  *branch_ccz
+	movl $2,%r0			# 36	[c=4]  *movsi_2
+	ret				# 31	[c=0]  return
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c
new file mode 100644
index 00000000000..3713c1ddd47
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-cmpzvsi.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+eq_extzvsi (bit_t x, int_t y)
+{
+  if (x.i == y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpzv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpzv_ccz
+	jeql .L3			# 39	[c=26]  *branch_ccz
+	movl $2,%r0			# 36	[c=4]  *movsi_2
+	ret				# 31	[c=0]  return
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c
new file mode 100644
index 00000000000..8a56451cd16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-0.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_ctzhi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = __builtin_ctz (*x);
+  if (*x == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movw *8(%ap),%r1		# 34	[c=24]  *movhi
+	ffs $0,$16,%r1,%r0		# 49	[c=4]  *ctzhi2_ccz
+	jeql .L3			# 38	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 33	[c=32]  *addhi3
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 2 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c
new file mode 100644
index 00000000000..db76da433e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzhi-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_ctzhi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = __builtin_ctz (*x + 1);
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtwl *8(%ap),%r0		# 34	[c=28]  *extendhisi2
+	incl %r0			# 35	[c=32]  *addsi3
+	ffs $0,$32,%r0,%r0		# 36	[c=4]  *ctzsi2
+	tstl %r0			# 37	[c=6]  *cmpsi_ccz/0
+	jeql .L2			# 38	[c=26]  *branch_ccz
+	addw2 $2,%r0			# 33	[c=32]  *addhi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */
+/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c
new file mode 100644
index 00000000000..b6078bc2c78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-0.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_ctzqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = __builtin_ctz (*x);
+  if (*x == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	movb *8(%ap),%r1		# 34	[c=24]  *movqi
+	ffs $0,$8,%r1,%r0		# 49	[c=4]  *ctzqi2_ccz
+	jeql .L3			# 38	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 33	[c=32]  *addqi3
+.L3:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 2 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c
new file mode 100644
index 00000000000..44311b98205
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzqi-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_ctzqi (int_t *w, int_t *x)
+{
+  int_t v;
+
+  v = __builtin_ctz (*x + 1);
+  if (v == 0)
+    *w = v;
+  else
+    *w = v + 2;
+}
+
+/* Expect assembly like:
+
+	cvtbl *8(%ap),%r0		# 34	[c=28]  *extendqisi2
+	incl %r0			# 35	[c=32]  *addsi3
+	ffs $0,$32,%r0,%r0		# 36	[c=4]  *ctzsi2
+	tstl %r0			# 37	[c=6]  *cmpsi_ccz/0
+	jeql .L2			# 38	[c=26]  *branch_ccz
+	addb2 $2,%r0			# 33	[c=32]  *addqi3
+.L2:
+
+ */
+
+/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */
+/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c
new file mode 100644
index 00000000000..bf84bdc0800
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-0.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_ctzsi (int_t x)
+{
+  int_t v;
+
+  v = __builtin_ctz (x);
+  if (x == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r1			# 32	[c=16]  *movsi_2
+	ffs $0,$32,%r1,%r0		# 45	[c=4]  *ctzsi2_ccz
+	jeql .L1			# 35	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 31	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c
new file mode 100644
index 00000000000..0cc40ed363c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ctzsi-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_ctzsi (int_t x)
+{
+  int_t v;
+
+  v = __builtin_ctz (x + 1);
+  if (v == 0)
+    return v;
+  else
+    return v + 2;
+}
+
+/* Expect assembly like:
+
+	addl3 4(%ap),$1,%r0		# 33	[c=40]  *addsi3
+	ffs $0,$32,%r0,%r0		# 34	[c=4]  *ctzsi2
+	tstl %r0			# 35	[c=6]  *cmpsi_ccz/0
+	jeql .L1			# 36	[c=26]  *branch_ccz
+	addl2 $2,%r0			# 32	[c=32]  *addsi3
+.L1:
+
+ */
+
+/* { dg-final { scan-rtl-dump-not "Splitting with gen_peephole2" "peephole2" } } */
+/* { dg-final { scan-assembler "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "cmpsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c
new file mode 100644
index 00000000000..50a6cdb18bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffshi.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+eq_ffshi (int_t *w, int_t *x)
+{
+  *w = __builtin_ffs (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$16,*8(%ap),%r1		# 40	[c=28]  *ctzhi2_ccz
+	jneq .L2			# 30	[c=26]  *branch_ccz
+	mnegl $1,%r1			# 26	[c=8]  *negsi2
+.L2:
+	addw3 %r1,$1,*4(%ap)		# 25	[c=32]  *addhi3
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzhi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c
new file mode 100644
index 00000000000..0b3ef0ff848
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffsqi.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+eq_ffsqi (int_t *w, int_t *x)
+{
+  *w = __builtin_ffs (*x);
+}
+
+/* Expect assembly like:
+
+	ffs $0,$8,*8(%ap),%r1		# 40	[c=28]  *ctzqi2_ccz
+	jneq .L2			# 30	[c=26]  *branch_ccz
+	mnegl $1,%r1			# 26	[c=8]  *negsi2
+.L2:
+	addb3 %r1,$1,*4(%ap)		# 25	[c=32]  *addqi3
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzqi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c
new file mode 100644
index 00000000000..0e321216020
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-eq-ffssi.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+eq_ffssi (int_t x)
+{
+  return __builtin_ffs (x);
+}
+
+/* Expect assembly like:
+
+	movl 4(%ap),%r1			# 28	[c=16]  *movsi_2
+	ffs $0,$32,%r1,%r0		# 41	[c=4]  *ctzsi2_ccz
+	jneq .L2			# 31	[c=26]  *branch_ccz
+	mnegl $1,%r0			# 27	[c=8]  *negsi2
+.L2:
+	incl %r0			# 26	[c=32]  *addsi3
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "ctzsi\[^ \]*_ccz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c
new file mode 100644
index 00000000000..9eb40c0bc8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andhi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v <= 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitw *8(%ap),*12(%ap)		# 56	[c=50]  *bithi_ccnz
+	jleq .L6			# 46	[c=26]  *branch_ccnz
+	movw $2,%r0			# 41	[c=4]  *movhi
+	movw %r0,*4(%ap)		# 40	[c=4]  *movhi
+	ret				# 52	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bithi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c
new file mode 100644
index 00000000000..14797b0c23a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+le_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v <= 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitb *8(%ap),*12(%ap)		# 56	[c=50]  *bitqi_ccnz
+	jleq .L6			# 46	[c=26]  *branch_ccnz
+	movb $2,%r0			# 41	[c=4]  *movqi
+	movb %r0,*4(%ap)		# 40	[c=4]  *movqi
+	ret				# 52	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitqi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c
new file mode 100644
index 00000000000..6d1193ee239
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-le-andsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+le_andsi (int_t x, int_t y)
+{
+  x &= y;
+  if (x <= 0)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	bitl 4(%ap),8(%ap)		# 58	[c=34]  *bitsi_ccnz
+	jgtr .L6			# 47	[c=26]  *branch_ccnz
+	movl $1,%r0			# 42	[c=4]  *movsi_2
+	ret				# 53	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitsi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c
new file mode 100644
index 00000000000..dd268493c77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpvsi.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+le_cmpvsi (bit_t x, int_t y)
+{
+  if (x.i <= y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpv_ccnz
+	jgtr .L6			# 39	[c=26]  *branch_ccnz
+	movl $1,%r0			# 35	[c=4]  *movsi_2
+	ret				# 45	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c
new file mode 100644
index 00000000000..3cf028a9560
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-le-cmpzvsi.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+le_cmpzvsi (uint_t x, int_t y, int_t z)
+{
+  int_t v;
+
+  v = x >> y;
+  if (v <= z)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 39	[c=40]  *subqi3/1
+	cmpzv 8(%ap),%r0,4(%ap),12(%ap)	# 53	[c=96]  *cmpzv_ccnz
+	jgtr .L6			# 42	[c=26]  *branch_ccnz
+	movl $1,%r0			# 37	[c=4]  *movsi_2
+	ret				# 48	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c
new file mode 100644
index 00000000000..0a0468b7988
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpvsi.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+leu_cmpvsi (bit_t x, uint_t y)
+{
+  uint_t v;
+
+  v = x.i;
+  if (v <= y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpv_cc
+	jgtru .L6			# 39	[c=26]  *branch_cc
+	movl $1,%r0			# 35	[c=4]  *movsi_2
+	ret				# 45	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpv\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c
new file mode 100644
index 00000000000..ca7cfe4dff9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-leu-cmpzvsi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+leu_cmpzvsi (uint_t x, int_t y, uint_t z)
+{
+  if (x >> y <= z)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 39	[c=40]  *subqi3/1
+	cmpzv 8(%ap),%r0,4(%ap),12(%ap)	# 53	[c=96]  *cmpzv_cc
+	jgtru .L6			# 42	[c=26]  *branch_cc
+	movl $1,%r0			# 37	[c=4]  *movsi_2
+	ret				# 48	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpzv\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c
new file mode 100644
index 00000000000..9eb40c0bc8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andhi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (HI))) int_t;
+
+void
+le_andhi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v <= 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitw *8(%ap),*12(%ap)		# 56	[c=50]  *bithi_ccnz
+	jleq .L6			# 46	[c=26]  *branch_ccnz
+	movw $2,%r0			# 41	[c=4]  *movhi
+	movw %r0,*4(%ap)		# 40	[c=4]  *movhi
+	ret				# 52	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bithi\[^ \]*_ccnz(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccnz\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c
new file mode 100644
index 00000000000..d71c46dad86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andqi.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (QI))) int_t;
+
+void
+lt_andqi (int_t *w, int_t *x, int_t *y)
+{
+  int_t v;
+
+  v = *x & *y;
+  if (v < 0)
+    *w = 1;
+  else
+    *w = 2;
+}
+
+/* Expect assembly like:
+
+	bitb *8(%ap),*12(%ap)		# 68	[c=50]  *bitqi_ccn
+	jlss .L6			# 58	[c=26]  *branch_ccn
+	movb $2,%r0			# 53	[c=4]  *movqi
+	movb %r0,*4(%ap)		# 52	[c=4]  *movqi
+	ret				# 64	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitqi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c
new file mode 100644
index 00000000000..4045b360ab5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-andsi.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef int __attribute__ ((mode (SI))) int_t;
+
+int_t
+lt_andsi (int_t x, int_t y)
+{
+  x &= y;
+  if (x < 0)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	bitl 4(%ap),8(%ap)		# 68	[c=34]  *bitsi_ccn
+	jgeq .L6			# 57	[c=26]  *branch_ccn
+	movl $1,%r0			# 52	[c=4]  *movsi_2
+	ret				# 63	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(cmpz?|tst). " } } */
+/* { dg-final { scan-assembler "bitsi\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c
new file mode 100644
index 00000000000..a50f322d488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpvsi.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+lt_cmpvsi (bit_t x, int_t y)
+{
+  if (x.i < y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpv_ccn
+	jgeq .L6			# 39	[c=26]  *branch_ccn
+	movl $1,%r0			# 35	[c=4]  *movsi_2
+	ret				# 45	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c
new file mode 100644
index 00000000000..de386431cfa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-lt-cmpzvsi.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+lt_cmpzvsi (uint_t x, int_t y, int_t z)
+{
+  int_t v;
+
+  v = x >> y;
+  if (v < z)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 39	[c=40]  *subqi3/1
+	cmpzv 8(%ap),%r0,4(%ap),12(%ap)	# 53	[c=96]  *cmpzv_ccn
+	jgeq .L6			# 42	[c=26]  *branch_ccn
+	movl $1,%r0			# 37	[c=4]  *movsi_2
+	ret				# 48	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpzv\[^ \]*_ccn(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_ccn\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c
new file mode 100644
index 00000000000..8eba5051278
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpvsi.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef signed int __attribute__ ((mode (SI))) int_t;
+typedef struct
+  {
+    int_t h : 7;
+    int_t i : 18;
+    int_t l : 7;
+  }
+bit_t;
+
+int_t
+ltu_cmpvsi (bit_t x, uint_t y)
+{
+  uint_t v;
+
+  v = x.i;
+  if (v < y)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	cmpv $7,$18,4(%ap),8(%ap)	# 50	[c=88]  *cmpv_cc
+	jgequ .L6			# 39	[c=26]  *branch_cc
+	movl $1,%r0			# 35	[c=4]  *movsi_2
+	ret				# 45	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpv\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
diff --git a/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c
new file mode 100644
index 00000000000..9cdee86b18e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vax/peephole2-ltu-cmpzvsi.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-peephole2 -dp" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+
+typedef unsigned int __attribute__ ((mode (SI))) uint_t;
+typedef int __attribute__ ((mode (SI))) int_t;
+
+uint_t
+ltu_cmpzvsi (uint_t x, int_t y, uint_t z)
+{
+  if (x >> y < z)
+    return 1;
+  else
+    return 2;
+}
+
+/* Expect assembly like:
+
+	subb3 8(%ap),$32,%r0		# 39	[c=40]  *subqi3/1
+	cmpzv 8(%ap),%r0,4(%ap),12(%ap)	# 53	[c=96]  *cmpzv_cc
+	jgequ .L6			# 42	[c=26]  *branch_cc
+	movl $1,%r0			# 37	[c=4]  *movsi_2
+	ret				# 48	[c=0]  return
+.L6:
+
+ */
+
+/* { dg-final { scan-rtl-dump-times "Splitting with gen_peephole2" 1 "peephole2" } } */
+/* { dg-final { scan-assembler-not "\t(bit|cmp|tst)\[bwl\] " } } */
+/* { dg-final { scan-assembler "cmpzv\[^ \]*_cc(/\[0-9\]+)?\n" } } */
+/* { dg-final { scan-assembler "branch_cc\n" } } */
-- 
2.11.0


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
@ 2020-11-20  3:38 Maciej W. Rozycki
  2020-11-20  3:34 ` [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Maciej W. Rozycki
                   ` (34 more replies)
  0 siblings, 35 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20  3:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

Hi,

 [Paul, there's a PDP11 piece for you further down here and then 29/31.]

 This is the much-desired refurbishment of the VAX backend.  A little bit 
past the end of Stage 1, which I apologise for and which I do hope is not 
going to make it a no-no for GCC 11.  I feel quite satisfied anyway I was 
able to overcome all the difficulties outside the development itself I was 
faced with throughout this effort and fit it into quite a tight schedule 
between my departure from Western Digital effective Sep 1st and now.

 Special thanks to Anders "Ragge" Magnusson for persuading me, on my trip 
to Luleå, Sweden back in 2015, to adopt Lizzie, his VAXstation 4000/60 he 
used to use for VAX/NetBSD development and decided to part with, as she 
turned out to be the only VAX machine in my possession ready to undertake 
the task of GCC verification, and also quite a mighty one for such a 
mature piece of hardware.

 The port has turned out to have some issues, which I decided to address 
so as not to have to propagate or correct breakage with the MODE_CC update 
itself, hence the 28 preparatory patches.  I might have skipped maybe two 
changes as not really necessary, such as the addition of `movmem' pattern, 
but they were really low-hanging fruit, and then easy to lose if not done 
right away.  I have split MODE_CC conversion test cases off due to the 
size of the change.

 Then there is a fix for the PDP11 backend addressing an issue I found in 
the handling of floating-point comparisons.  Unlike all the other changes 
this one has not been regression-tested, not even built as I have no idea 
how to prepare a development environment for a PDP11 target (also none of 
my VAX pieces is old enough to support PDP11 machine code execution).

 Still I am fairly sure it is a correct change to make, and you should be 
able to confirm it quite easily perhaps by picking the same test case from 
31/31 that I used for the example RTL dump in 28/31 and using it along 
with said dump to match what the PDP11 backend produces.  Maybe you can 
use these test cases for PDP11 verification as well, as they are pretty 
generic except for the assembly match patterns of course.

 These changes have been regression-tested throughout development with the 
`vax-netbsdelf' target running NetBSD 9.0, using said VAXstation 4000/60, 
which uses the Mariah implemementation of the VAX architecture.  The host 
used was `powerpc64le-linux-gnu' and occasionally `x86_64-linux-gnu' as 
well; changes outside the VAX backend were all natively bootstrapped and 
regression-tested with both these hosts.

 Target regression-testing has been done across all the components that 
build (01/31 is required to build libgomp at `-O2), meaning the following 
parts have been excluded for the reasons stated:

1. libada -- not ported to VAX/NetBSD, machine/OS bindings not present.

2. libgfortran -- oddly enough for Fortran a piece requires IEEE 754
   floating-point arithmetic (possibly a porting problem too).

3. libgo -- not ported to VAX/NetBSD, machine/OS bindings are not present.

and the absence of the respective libraries caused failures with the 
respective frontends as well.

 One regression has been nominally caused, in C frontend testing:

FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects

however it is a symptom of an unrelated bug in the LTO wrapper, which 
clears the PIC flag unconditionally:

    case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */
      flag_pic = 0;
      flag_pie = 0;
      flag_shlib = 0;
      break;

and causes a legitimate assembly warning:

/tmp/ccG0X3DQ.s: Assembler messages:
/tmp/ccG0X3DQ.s:17: Warning: Symbol n used as immediate operand in PIC mode.
/tmp/ccG0X3DQ.s:26: Warning: Symbol n used as immediate operand in PIC mode.

similarly to a preexisting failure for the same test case at `-O0':

FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin

and numerous other ones.  I'll file a PR to track this problem and see if 
I can address it quickly now that I'm done with the MODE_CC conversion, 
with the understanding that it may not be suitable for GCC 11 at this 
point of the development cycle.

 As I have refreshed the tree again for this submission and verification 
takes short of 48 hours per run, I'll be scheduling another full cycle and 
expect to have updated results in about a week's time as all being well I 
imagine I'll have to go throug three runs for the base results, results 
for the preparatory changes, and then the final results.  I'll see if I 
can arrange and run some benchmarking too.

 See individual change descriptions for details and code quality stats.

 Last not least for easier access I have made these changes available at 
<git://gcc.gnu.org/git/gcc.git>, `users/macro/vax-mode-cc' branch.

 Comments, questions, concerns?

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (30 preceding siblings ...)
  2020-11-20  3:37 ` [PATCH 31/31] PR target/95294: VAX: Add test cases for " Maciej W. Rozycki
@ 2020-11-20  7:58 ` Anders Magnusson
  2020-11-23 20:31   ` Maciej W. Rozycki
  2020-11-21 21:02 ` Toon Moene
                   ` (2 subsequent siblings)
  34 siblings, 1 reply; 117+ messages in thread
From: Anders Magnusson @ 2020-11-20  7:58 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches

Morning Maciej,
>   Then there is a fix for the PDP11 backend addressing an issue I found in
> the handling of floating-point comparisons.  Unlike all the other changes
> this one has not been regression-tested, not even built as I have no idea
> how to prepare a development environment for a PDP11 target (also none of
> my VAX pieces is old enough to support PDP11 machine code execution).
You could use simh /w 2.11BSD, or if you want to test it on real 
hardware I have a 11/83 where you could test?

-- R

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-20  3:34 ` [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Maciej W. Rozycki
@ 2020-11-20 10:55   ` Eric Botcazou
  2020-11-20 15:30     ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Eric Botcazou @ 2020-11-20 10:55 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson

> First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.

> 	gcc/
> 	PR target/58901
> 	* reload.c (reload_inner_reg_of_subreg): Also request reloading
> 	for pseudo registers associated with mode dependent memory
> 	references.
> 	(push_reload): Handle pseudo registers.

The handling of this family of reloads is supposed to be done by the block of 
code just above though, i.e. at line 1023.  Can't we add the test based on 
mode_dependent_address_p to this block, e.g. after:

	  || (REG_P (SUBREG_REG (in))
	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
					 GET_MODE (SUBREG_REG 
(in)), inmode))))

instead?

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-20 10:55   ` Eric Botcazou
@ 2020-11-20 15:30     ` Maciej W. Rozycki
  2020-11-24  6:19       ` [PATCH v2 " Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-20 15:30 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, Anders Magnusson

On Fri, 20 Nov 2020, Eric Botcazou wrote:

> > 	gcc/
> > 	PR target/58901
> > 	* reload.c (reload_inner_reg_of_subreg): Also request reloading
> > 	for pseudo registers associated with mode dependent memory
> > 	references.
> > 	(push_reload): Handle pseudo registers.
> 
> The handling of this family of reloads is supposed to be done by the block of 
> code just above though, i.e. at line 1023.  Can't we add the test based on 
> mode_dependent_address_p to this block, e.g. after:
> 
> 	  || (REG_P (SUBREG_REG (in))
> 	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
> 	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
> 					 GET_MODE (SUBREG_REG 
> (in)), inmode))))
> 
> instead?

 Thank you for your input, I'll have a look.  Coming from Matt this is the 
only change of the series I have just merged without looking into it too 
much, so as not to spend too much time with side issues (there were too 
many already).

 It'll take me a couple of days to push the new version through regression 
testing, and I'll post it once that is complete along with any other 
updates someone may request.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 02/31] VAX: Remove `c' operand format specifier overload
  2020-11-20  3:34 ` [PATCH 02/31] VAX: Remove `c' operand format specifier overload Maciej W. Rozycki
@ 2020-11-20 23:16   ` Jeff Law
  2020-11-24  1:12   ` Segher Boessenkool
  1 sibling, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:16 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> The `c' operand format specifier is handled directly by the middle end
> in `output_asm_insn':
>
>    %cN means require operand N to be a constant
>       and print the constant expression with no punctuation.
>
> however it resorts to the target for constants that are not valid
> addresses:
>
> 	    else if (letter == 'c')
> 	      {
> 		if (CONSTANT_ADDRESS_P (operands[opnum]))
> 		  output_addr_const (asm_out_file, operands[opnum]);
> 		else
> 		  output_operand (operands[opnum], 'c');
> 	      }
>
> The VAX backend expects the fallback never to happen and overloads `c'
> with the branch condition code.  This is confusing however and it is not
> like we are short of letters, so instead make the branch condition code
> use `k', and then for consistency make `K' the reverse branch condition
> code format specifier.  This is safe to do as we provide no means to use
> a computed branch condition code in user `asm'.
>
> 	gcc/
> 	* config/vax/vax.c (print_operand): Replace `c' and `C' with
> 	`k' and `K' respectively.
> 	* config/vax/vax.md (*branch, *branch_reversed): Update
> 	accordingly.
OK.

I wonder if other targets have the same problem.  But that doesn't
affect this patch.

Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels
  2020-11-20  3:34 ` [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels Maciej W. Rozycki
@ 2020-11-20 23:17   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:17 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> It makes sense to use what other targets do and run all the VAX test
> cases over all the usual optimization levels, so make `vax.exp' use our
> `gcc-dg-runtest' rather than the generic `dg-runtest' test driver.
>
> This breaks `pr56875.c' however, which is optimized away at levels above
> `-O0' as a result of how it has been written for calculations to make no
> effect:
>
> FAIL: gcc.target/vax/pr56875.c   -O1   scan-assembler ashq .*,\\$0xffffffffffffffff,
> FAIL: gcc.target/vax/pr56875.c   -O2   scan-assembler ashq .*,\\$0xffffffffffffffff,
> FAIL: gcc.target/vax/pr56875.c   -O3 -g   scan-assembler ashq .*,\\$0xffffffffffffffff,
> FAIL: gcc.target/vax/pr56875.c   -Os   scan-assembler ashq .*,\\$0xffffffffffffffff,
> FAIL: gcc.target/vax/pr56875.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none   scan-assembler ashq .*,\\$0xffffffffffffffff,
> FAIL: gcc.target/vax/pr56875.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects   scan-assembler ashq .*,\\$0xffffffffffffffff,
>
> Rather than keeping it at `-O0' update the test case for its code to do
> make effect while retaining its sense.  Also reformat it according to
> our requirements.
>
> 	gcc/testsuite/
> 	* gcc.target/vax/vax.exp: Use `gcc-dg-runtest' rather than
> 	`dg-runtest'.
> 	* gcc.target/vax/pr56875.c (dg-options): Make empty.
> 	(a): Rewrite for calculations to make effect.  Reformat.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin
  2020-11-20  3:34 ` [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin Maciej W. Rozycki
@ 2020-11-20 23:19   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:19 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> The `builtins.md' machine description fragment is not included anywhere
> and is therefore dead code, which has become bitrotten due to non-use.
>
> If actually enabled, it does not build due to the use of an unknown `t'
> constraint:
>
> .../gcc/config/vax/builtins.md:42:1: error: undefined machine-specific constraint at this point: "t"
> .../gcc/config/vax/builtins.md:42:1: note:  in operand 1
>
> which came from commit becb93d02cc1 ("builtins.md (ffssi2_internal):
> Correct constraint."), which was not applied as posted and reviewed; `T'
> was meant to be used instead.
>
> Once this has been fixed this code still fails building:
>
> .../gcc/config/vax/builtins.md: In function 'rtx_def* gen_ffssi2(rtx, rtx)':
> .../gcc/config/vax/builtins.md:35:19: error: 'gen_bne' was not declared in this
> scope; did you mean 'gen_use'?
>    35 |   emit_jump_insn (gen_bne (label));
>       |                   ^~~~~~~
>       |                   gen_use
> make[2]: *** [Makefile:1122: insn-emit.o] Error 1
>
> Finally the FFS machine instruction sets the Z condition code according
> to the comparison of the value held in the source operand against zero
> rather than the value held in the target operand.  If the source operand
> is found hold zero, then the target operand is set to the width of the
> source operand, 32 for SImode (FFS supports arbitrary widths).
>
> Correct the build issues then and update RTL to match the operation of
> the machine instruction.  A test case will be added separately.
>
> 	gcc/
> 	* config/vax/builtins.md (ffssi2): Make preparation statements
> 	actually buildable.
> 	(ffssi2_internal): Fix input constraints; make the RTL pattern
> 	match reality for `cc0'.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches
  2020-11-20  3:34 ` [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches Maciej W. Rozycki
@ 2020-11-20 23:20   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:20 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> Regardless of the machine mode all the interlocked branches of the same
> kind, one of the two provided by the ISA, use the same RTL patterns and
> machine instructions, except for the memory operand's constraint.
>
> Remove code duplication then and make use of a mode iterator combined
> with an attribute to expand the same insn patterns with the constraint
> suitably substituted from a single template.  No functional change.
>
> 	gcc/
> 	* config/vax/builtins.md (bb_mem): New mode attribute.
> 	(jbbssiqi, jbbssihi, jbbssisi): Fold insns into...
> 	(jbbssi<mode>): ... this.
> 	(jbbcciqi, jbbccihi, jbbccisi): Likewise...
> 	(jbbcci<mode>): ... this.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 10/31] VAX: Use an int iterator to produce individual interlocked branches
  2020-11-20  3:34 ` [PATCH 10/31] VAX: Use an int " Maciej W. Rozycki
@ 2020-11-20 23:20   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:20 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> With mode-specific interlocked branch insns already folded into iterated
> templates now fold the two templates into one too, observing that the
> only difference between them is the value of the bit branched on, which
> is of course reflected both in the RTL expression and the instruction
> produced.  Use an int iterator to iterate over the bit value, making use
> of the newly-added wide integer support, and substituting patterns as
> necessary to produce equivalent individual insns.  No functional change.
>
> 	gcc/
> 	* config/vax/builtins.md (bit): New int iterator.
> 	(ccss): New int attribute.
> 	(jbbssi<mode>, jbbcci<mode>): Fold insns into...
> 	(jbb<ccss>i<mode>): ... this.
 OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional
  2020-11-20  3:35 ` [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional Maciej W. Rozycki
@ 2020-11-20 23:21   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:21 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> Test cases will follow.
>
> 	gcc/
> 	* config/vax/vax.md: Include `builtins.md'.
OK.  THough probably shouldn't commit individually, but instead once all
the prereqs are done.
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation
  2020-11-20  3:35 ` [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation Maciej W. Rozycki
@ 2020-11-20 23:22   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:22 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> 	gcc/testsuite/
> 	* gcc.target/vax/ffssi.c: New test.
OK. Same comment about prereqs.

jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release'
  2020-11-20  3:35 ` [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release' Maciej W. Rozycki
@ 2020-11-20 23:22   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:22 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> Based on gcc.dg/pr61756.c.
>
> 	gcc/testsuite/
> 	* gcc.target/vax/bbcci.c: New test.
> 	* gcc.target/vax/bbssi.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 15/31] VAX: Provide the `ctz' operation
  2020-11-20  3:35 ` [PATCH 15/31] VAX: Provide the `ctz' operation Maciej W. Rozycki
@ 2020-11-20 23:23   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:23 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> Our `ffssi2_internal' pattern and the machine FFS instruction, which
> technically is a bitfield operation, match the `ctz' operation exactly,
> with the result produced for the bitfield source operand of zero equal
> to its width as specified with another machine instruction operand, not
> directly expressed in RTL and currently hardcoded in the assembly code
> produced.  In our terms this is the bit size of the machine mode used,
> and although it's SImode now let's be flexible for an upcoming change.
>
> The operation also sets the Z condition code according to the value of
> the source operand.
>
> 	gcc/
> 	* config/vax/builtins.md (ffssi2_internal): Rename insn to...
> 	(ctzsi2): ... this.  Update the RTL operation.
> 	(ffssi2): Update accordingly.
> 	* gcc/config/vax/vax.c (vax_notice_update_cc): Handle CTZ.
> 	* gcc/config/vax/vax.h (CTZ_DEFINED_VALUE_AT_ZERO): New macro.
>
> 	gcc/testsuite/
> 	* gcc.target/vax/ctzsi.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations
  2020-11-20  3:35 ` [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations Maciej W. Rozycki
@ 2020-11-20 23:24   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:24 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> The FFS machine instruction provides for arbitrary input bitfield widths
> so take advantage of this and convert `ffssi2' and `ctzsi2' to templates
> for all the three of QI, HI, SI machine modes.
>
> Test cases will be added separately.
>
> 	gcc/
> 	* config/vax/builtins.md (width): New mode attribute.
> 	(ffssi2): Rework expander into...
> 	(ffs<mode>2): ... this.
> 	(ctzsi2): Rework insn into...
> 	(ctz<mode>2): ... this.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations
  2020-11-20  3:35 ` [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations Maciej W. Rozycki
@ 2020-11-20 23:24   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:24 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> The middle end does not refer to `ctzqi2'/`ctzhi2' or `ffsqi2'/`ffshi2'
> patterns by name where `__builtin_ctz' or `__builtin_ffs' respectively
> is invoked for an argument of the QImode or HImode type, and instead it
> extends the data type before passing it to `ctzsi2' or `ffssi2'.
>
> Avoid the redundant operation and use a peephole2 to convert it to the
> right RTL expression that will collapse the two operations into a single
> machine instruction instead unless we need the extended intermediate
> result for another purpose.
>
> 	gcc/
> 	* config/vax/builtins.md: Add a peephole2 for QImode and HImode
> 	`ctz' operations.
> 	(any_extend): New code iterator.
>
> 	gcc/testsuite/
> 	* gcc.target/vax/ctzhi.c: New test.
> 	* gcc.target/vax/ctzqi.c: New test.
> 	* gcc.target/vax/ffshi.c: New test.
> 	* gcc.target/vax/ffsqi.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction
  2020-11-20  3:35 ` [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction Maciej W. Rozycki
@ 2020-11-20 23:25   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:25 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> 	gcc/testsuite/
> 	* gcc.target/vax/cpymem.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 19/31] VAX: Add the `movmemhi' instruction
  2020-11-20  3:35 ` [PATCH 19/31] VAX: Add the `movmemhi' instruction Maciej W. Rozycki
@ 2020-11-20 23:25   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-20 23:25 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> The MOVC3 machine instruction has `memmove' semantics[1]:
>
> "The operation of the instruction is such that overlap of the source and
> destination strings does not affect the result."
>
> so use it to provide the `movmemhi' instruction as well.
>
> References:
>
> [1] DEC STD 032-0 "VAX Architecture Standard", Digital Equipment
>     Corporation, A-DS-EL-00032-00-0 Rev J, December 15, 1989, Section
>     3.10 "Character-String Instructions", p. 3-162
>
> 	gcc/
> 	* config/vax/vax.md (cpymemhi1): Rename insn to...
> 	(movmemhi1): ... this.
> 	(cpymemhi): Update accordingly.  Remove constraints.
> 	(movmemhi): New expander.
>
> 	gcc/testsuite/
> 	* gcc.target/vax/movmem.c: New test.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P
  2020-11-20  3:34 ` [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P Maciej W. Rozycki
@ 2020-11-21  3:17   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  3:17 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> The VAX ELF psABI does not permit the use of all hardware operand modes
> for PIC symbol references due to the need to use PC-relative addressing
> for symbols that end up local and the need to make references indirect
> symbols that end up global.
>
> Therefore symbols referred as immediates may only be used with the move
> and push address (MOVA and PUSHA) instructions and their PC-relative
> displacement address mode, as there is no genuine PC-relative immediate
> available that all the other instructions would have to use.
>
> Furthermore global symbol references must not have an offset applied,
> which has to be added with a separate instruction, because there is no
> support now for GOT entries for external `symbol+offset' references, so
> any indirect GOT references made by the static linker from the original
> direct symbol references must not have an addend applied.  Consequently
> no addend is allowed even if a given external symbol turns out local,
> for whatever reason, at the static link time.
>
> Define the LEGITIMATE_PIC_OPERAND_P macro then, a corresponding function
> and predicate to exclude the relevant expressions as required, and then
> a constraint so that reloads are produced where needed, and use the new
> facilities in the machine description, folding corresponding duplicated
> patterns for local and external symbols together.  Rewrite predicates to
> make use of the new function, rename them to match their sense and also
> remove ones no longer used.
>
> All this fixing an ICE like this:
>
> during RTL pass: postreload
> .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c: In function 'testE':
> .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:89:1: internal compiler error: in reload_combine_note_use, at postreload.c:1559
> .../gcc/testsuite/gcc.c-torture/execute/20040709-2.c:96:65: note: in expansion of macro 'T'
> 0x10fe84cb reload_combine_note_use
> 	.../gcc/postreload.c:1559
> 0x10fe8857 reload_combine_note_use
> 	.../gcc/postreload.c:1621
> 0x10fe8303 reload_combine_note_use
> 	.../gcc/postreload.c:1517
> 0x10fe7c7b reload_combine
> 	.../gcc/postreload.c:1408
> 0x10fe3417 reload_cse_regs
> 	.../gcc/postreload.c:67
> 0x10feaf9f execute
> 	.../gcc/postreload.c:2358
>
> due to the presence of a pseudo register post-reload:
>
> (insn 435 228 229 13 (set (reg:SI 1 %r1)
>         (mem/c:SI (reg/f:SI 341) [25 sE+12 S4 A8])) ".../gcc/testsuite/gcc.c-torture/execute/20040709-2.c":96:65 12 {movsi_2}
>      (nil))
>
> (due to the use of an offset `sE+12' symbol reference) and removing
> these regressions:
>
> FAIL: gcc.c-torture/execute/20040709-2.c   -O2  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O2  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -g  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O3 -g  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-2.c   -Os  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-2.c   -Os  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O2  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O2  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O3 -g  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O3 -g  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-3.c   -Os  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-3.c   -Os  (test for excess errors)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
> FAIL: gcc.c-torture/execute/20040709-3.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
> FAIL: gcc.dg/torture/pr52028.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
> FAIL: gcc.dg/torture/pr52028.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
>
> 	gcc/
> 	* config/vax/constraints.md (A): New constraint.
> 	* config/vax/predicates.md (external_symbolic_operand)
> 	(external_const_operand): Remove predicates.
> 	(local_symbolic_operand): Rename to...
> 	(pic_symbolic_operand): ... this, and rework.
> 	(external_memory_operand): Rename to...
> 	(non_pic_external_memory_operand): ... this, and rework.
> 	(illegal_blk_memory_operand, illegal_addsub_di_memory_operand):
> 	Update accordingly.
> 	* config/vax/vax-protos.h (vax_acceptable_pic_operand_p): New
> 	prototype.
> 	* config/vax/vax.c (vax_acceptable_pic_operand_p): New function.
> 	(vax_output_int_add): Update according to predicate rework.
> 	* config/vax/vax.h (LEGITIMATE_PIC_OPERAND_P): New macro.
> 	* config/vax/vax.md (pushlclsymreg, pushextsymreg): Fold
> 	together, and rename to...
> 	(*pushsymreg): ... this.  Use the `pic_symbolic_operand'
> 	predicate and the `A' constraint for the displacement operand.
> 	(movlclsymreg, movextsymreg): Fold together, and rename to...
> 	(*movsymreg): ... this.  Use the `pic_symbolic_operand'
> 	predicate and the `A' constraint for the displacement operand.
> 	(pushextsym, pushlclsym): Fold together, and rename to...
> 	(*pushsym): ... this.  Use the `pic_symbolic_operand' predicate
> 	and the `A' constraint for the displacement operand.
> 	(movextsym, movlclsym): Fold together, and rename to...
> 	(*movsym): ... this.  Use the `pic_symbolic_operand' predicate
> 	and the `A' constraint for the displacement operand.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 05/31] VAX: Rationalize expression and address costs
  2020-11-20  3:34 ` [PATCH 05/31] VAX: Rationalize expression and address costs Maciej W. Rozycki
@ 2020-11-21  3:48   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  3:48 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> Expression costs are required to be given in terms of COSTS_N_INSNS (n),
> which is defined to stand for the count of single fast instructions, and
> actually returns `n * 4'.  The VAX backend however instead operates on
> naked numbers, causing an anomaly for the integer const zero rtx, where
> the cost given is 4 as opposed to 1 for integers in the [1:63] range, as
> well as -1 for comparisons.  This is because the value of 0 returned by
> `vax_rtx_costs' is converted to COSTS_N_INSNS (1) in `pattern_cost':
>
>   return cost > 0 ? cost : COSTS_N_INSNS (1);
>
> Consequently, where feasible, 1 or -1 are preferred over 0 by the middle
> end causing code pessimization, e.g. rather than producing this:
>
> 	subl2 $4,%sp
> 	movl 4(%ap),%r0
> 	jgtr .L2
> 	addl2 $2,%r0
> .L2:
> 	ret
>
> or this:
>
> 	subl2 $4,%sp
> 	addl3 4(%ap),8(%ap),%r0
> 	jlss .L6
> 	addl2 $2,%r0
> .L6:
> 	ret
>
> code is produced like this:
>
> 	subl2 $4,%sp
> 	movl 4(%ap),%r0
> 	cmpl %r0,$1
> 	jgeq .L2
> 	addl2 $2,%r0
> .L2:
> 	ret
>
> or this:
>
> 	subl2 $4,%sp
> 	addl3 4(%ap),8(%ap),%r0
> 	cmpl %r0,$-1
> 	jleq .L6
> 	addl2 $2,%r0
> .L6:
> 	ret
>
> from this:
>
> int
> compare_mov (int x)
> {
>   if (x > 0)
>     return x;
>   else
>     return x + 2;
> }
>
> and this:
>
> int
> compare_add (int x, int y)
> {
>   int z;
>
>   z = x + y;
>   if (z < 0)
>     return z;
>   else
>     return z + 2;
> }
>
> respectively, which is slower and larger both at a time.
>
> Furthermore once the backend is converted to MODE_CC this anomaly makes
> it usually impossible to remove redundant comparisons in the comparison
> elimination pass, because most VAX instructions set the condition codes
> as per the relation of the instruction's result to 0 and not -1.
>
> The middle end has some other assumptions as to rtx costs being given in
> terms of COSTS_N_INSNS, so wrap all the VAX rtx costs then as they stand
> into COSTS_N_INSNS invocations, effectively scaling the costs by 4 while
> preserving their relative values, except for the integer const zero rtx
> given the value of `COSTS_N_INSNS (1) / 2', half of a fast instruction
> (this can be further halved if needed in the future).
>
> Adjust address costs likewise so that they remain proportional to the
> new absolute values of rtx costs.
>
> Code size stats are as follows, collected from 17639 executables built
> in `check-c' GCC testing:
>
>               samples average  median
> --------------------------------------
> regressions      1420  0.400%  0.195%
> unchanged       13811  0.000%  0.000%
> progressions     2408 -0.504% -0.201%
> --------------------------------------
> total           17639 -0.037%  0.000%
>
> with a small number of outliers only (over 5% size change):
>
> old     new     change  %change filename
> ----------------------------------------------------
> 4991    5249     258     5.1693 981001-1.exe
> 2637    2777     140     5.3090 interchange-6.exe
> 2187    2307     120     5.4869 sprintf.x7
> 3969    4197     228     5.7445 pr28982a.exe
> 8264    8816     552     6.6795 vector-compare-1.exe
> 5199    5575     376     7.2321 pr28982b.exe
> 2113    2411     298    14.1031 20030323-1.exe
> 2113    2411     298    14.1031 20030323-1.exe
> 2113    2411     298    14.1031 20030323-1.exe
>
> so it seems we are looking good, and we have complementing reductions
> to compensate:
>
> old     new     change  %change filename
> ----------------------------------------------------
> 2919    2631    -288    -9.8663 pr57521.exe
> 3427    3167    -260    -7.5868 sabd_1.exe
> 2985    2765    -220    -7.3701 ssad-run.exe
> 2985    2765    -220    -7.3701 ssad-run.exe
> 2985    2765    -220    -7.3701 usad-run.exe
> 2985    2765    -220    -7.3701 usad-run.exe
> 4509    4253    -256    -5.6775 vshuf-v2sf.exe
> 4541    4285    -256    -5.6375 vshuf-v2si.exe
> 4673    4417    -256    -5.4782 vshuf-v2df.exe
> 2993    2841    -152    -5.0785 abs-2.x4
> 2993    2841    -152    -5.0785 abs-3.x4
>
> This actually causes `loop-8.c' to regress:
>
> FAIL: gcc.dg/loop-8.c scan-rtl-dump-times loop2_invariant "Decided" 1
> FAIL: gcc.dg/loop-8.c scan-rtl-dump-not loop2_invariant "without introducing a new temporary register"
>
> but upon a closer inspection this is a red herring.  Old code looks as
> follows:
>
> 	.file	"loop-8.c"
> 	.text
> 	.align 1
> .globl f
> 	.type	f, @function
> f:
> 	.word 0
> 	subl2 $4,%sp
> 	movl 4(%ap),%r2
> 	movl 8(%ap),%r3
> 	movl $42,(%r2)
> 	clrl %r0
> 	movl $42,%r1
> 	movl %r1,%r4
> 	jbr .L2
> .L5:
> 	movl %r4,%r1
> .L2:
> 	movl %r1,(%r3)[%r0]
> 	incl %r0
> 	cmpl %r0,$100
> 	jeql .L6
> 	movl $42,(%r2)[%r0]
> 	bicl3 $-2,%r0,%r1
> 	jeql .L5
> 	movl %r0,%r1
> 	jbr .L2
> .L6:
> 	ret
> 	.size	f, .-f
>
> while new one is like below:
>
> 	.file	"loop-8.c"
> 	.text
> 	.align 1
> .globl f
> 	.type	f, @function
> f:
> 	.word 0
> 	subl2 $4,%sp
> 	movl 4(%ap),%r2
> 	movl $42,(%r2)+
> 	movl 8(%ap),%r1
> 	clrl %r0
> 	movl $42,%r3
> 	movzbl $100,%r4
> 	movl %r3,%r5
> 	jbr .L2
> .L5:
> 	movl %r5,%r3
> .L2:
> 	movl %r3,(%r1)+
> 	incl %r0
> 	cmpl %r0,%r4
> 	jeql .L6
> 	movl $42,(%r2)+
> 	bicl3 $-2,%r0,%r3
> 	jeql .L5
> 	movl %r0,%r3
> 	jbr .L2
> .L6:
> 	ret
> 	.size	f, .-f
>
> and is clearly better: not only it is smaller, but it also uses the
> post-increment rather than indexed addressing mode in the loop, of
> which the former comes for free in terms of both performance and code
> size while the latter causes an extra byte per operand to be produced
> for the index register and also incurs an execution penalty for the
> extra address calculation.
>
> Exclude the case from VAX testing then, as already done for some other
> targets and discussed with commit d242fdaec186 ("gcc.dg/loop-8.c: Skip
> for mmix.").
>
> 	gcc/
> 	* config/vax/vax.c (vax_address_cost): Express the cost in terms
> 	of COSTS_N_INSNS.
> 	(vax_rtx_costs): Likewise.
>
> 	gcc/testsuite/
> 	* gcc.dg/loop-8.c: Exclude for `vax-*-*'.
> 	* gcc.target/vax/compare-add-zero.c: New test.
> 	* gcc.target/vax/compare-mov-zero.c: New test.
So this brings a much higher degree of consistency to the vax costing
model, which is definitely a good thing.   While expressing in terms of
COSTS_N_INSNS may not always be correct, this patch does use
COSTS_N_INSNS in many cases where it was probably missing before.   If
we feel the need to refine it further, that can certainly be done.

Note that even in the cases where it may not be correct, it's not
terrible.  Consider POST_INC/PRE_DEC.  I have a hard time seeing how
those would cost 2 fast instructions most of the time.  However, if we
have to reload the expression, then COSTS_N_INSNS (2) is probably
reasonably accurate.  And I suspect the vax port is a lot more likely to
rely on reloading to match constraints than it is on using tight
predicates where constraints are more for driving instruction selection
than reloading (as we see on riscy targets).

Ultimately the proof is in the data.  Obviously someone looking to
improve things further can do so and this patch makes the bar higher for
any such changes.

OK.

Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns
  2020-11-20  3:36 ` [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns Maciej W. Rozycki
@ 2020-11-21  4:05   ` Jeff Law
  2020-11-30 16:02     ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:05 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> It makes no sense for insn operand predicates, as long as they accept a
> register operand, to be more restrictive than the set of the associated
> constraints, because expand will choose the insn based on the relevant
> operand being a pseudo register then and reload will keep it happily as
> an immediate if a constraint permits it.  So the restriction posed by
> such a predicate will be happily ignored, and moreover if a splitter is
> added, such as required for MODE_CC support, the new instructions will
> reject the original operands supplied, causing an ICE like below:
>
> .../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: Error: could not split insn
> (insn 90 662 663 (set (reg:DI 10 %r10 [orig:97 _235 ] [97])
>         (mult:DI (sign_extend:DI (mem/c:SI (plus:SI (reg/f:SI 13 %fp)
>                         (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S4 A32]))
>             (sign_extend:DI (const_int -51 [0xffffffffffffffcd])))) 299 {mulsidi3}
>      (expr_list:REG_EQUAL (mult:DI (sign_extend:DI (subreg:SI (mem/c:DI (plus:SI (reg/f:SI 13 %fp)
>                             (const_int -800 [0xfffffffffffffce0])) [14 %sfp+-800 S8 A32]) 0))
>             (const_int -51 [0xffffffffffffffcd]))
>         (nil)))
> during RTL pass: final
> .../gcc/testsuite/gfortran.dg/graphite/PR67518.f90:44:0: internal compiler error: in final_scan_insn_1, at final.c:3073
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <https://gcc.gnu.org/bugs/> for instructions.
>
> Change the predicates used with the widening multiply and multiply-add
> insns to allow immediates then, just as the constraints and the machine
> instructions produced permit.
>
> Also give the insns names, for easier reference here and elsewhere.
>
> 	gcc/
> 	* config/vax/vax.md (mulsidi3): Fix the multiplicand predicates.
> 	(*maddsidi4, *maddsidi4_const): Likewise.  Name insns.
OK
jeff

ps.  Yes, I skipped the insv/extv changes.  They're usually a rats nest
of special cases.  We'll come back to them.


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 26/31] VAX: Correct issues with commented-out insns
  2020-11-20  3:36 ` [PATCH 26/31] VAX: Correct issues with commented-out insns Maciej W. Rozycki
@ 2020-11-21  4:05   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:05 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> Correct issues with commented-out insns, which fail to build if enabled:
>
> .../gcc/config/vax/vax.md:503:1: repeated operand number 1
> .../gcc/config/vax/vax.md:503:1: repeated operand number 2
>
> and then when the issue with the repeated operands has been corrected:
>
> .../gcc/config/vax/vax.md:107:1: destination operand 0 allows non-lvalue
> .../gcc/config/vax/vax.md:503:1: destination operand 0 allows non-lvalue
> .../gcc/config/vax/vax.md:503:1: destination operand 3 allows non-lvalue
> .../gcc/config/vax/vax.md:744:1: destination operand 0 allows non-lvalue
>
> Fix the RTL with the repeated operands and change the relevant output
> operand predicates not to allow immediates.
>
> Also emit MOVO rather than MOVH assembly instruction with the `movti'
> insn so that the condition codes are set according to the integer rather
> than floating-point interpretation of the datum moved, as expected with
> the operation associated with the pattern.
>
> Finally give `*amulsi4' a name, for easier reference here and elsewhere.
>
> We may eventually want to have some of these insns enabled at `-Os'.
>
> ChangeLog:
>
> 	* gcc/config/vax/vax.md (movti): Fix output predicate.  Emit
> 	`movo' rather than `movh'.
> 	(divmoddisi4): Fix output predicates, correct RTL.
> 	(*amulsi4): Name insn.  Fix output predicate.
OK
Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent
  2020-11-20  3:36 ` [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Maciej W. Rozycki
@ 2020-11-21  4:06   ` Jeff Law
  2020-11-24  1:37   ` Segher Boessenkool
  1 sibling, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:06 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> Use a double colon to introduce the comments like elsewhere throughout
> the VAX machine description.
>
> 	gcc/
> 	* config/vax/vax.md (divmoddisi4, *amulsi4): Make the comment
> 	notation consistent with the rest of the file.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-11-20  3:36 ` [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant Maciej W. Rozycki
@ 2020-11-21  4:07   ` Jeff Law
  2020-12-15  8:26   ` Martin Liška
  1 sibling, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:07 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> We do not define a comparison operation between floating-point and
> integer data, including integer zero constant.  Consequently the RTL
> instruction stream presented to the post-reload comparison elimination
> pass will include, where applicable, floating-point comparison insns
> against `const_double:DF 0.0 [0x0.0p+0]' rather than `const_int 0 [0]',
> meaning that the latter expression will not match when used in machine
> description.
>
> Use `const_double_zero' then for the relevant patterns to match the
> intended RTL instructions.
>
> 	gcc/
> 	* config/pdp11/pdp11.md (fcc_cc, fcc_ccnz): Use
> 	`const_double_zero' to express double zero constant.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 31/31] PR target/95294: VAX: Add test cases for MODE_CC representation
  2020-11-20  3:37 ` [PATCH 31/31] PR target/95294: VAX: Add test cases for " Maciej W. Rozycki
@ 2020-11-21  4:08   ` Jeff Law
  2020-12-05 18:40     ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:08 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:37 PM, Maciej W. Rozycki wrote:
> 	gcc/testsuite/
> 	PR target/95294
> 	* gcc.target/vax/cmpelim-eq-adddf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-addhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-addqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-addsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-addsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-andhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-andqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-andsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-ashlsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-ashrsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-divdf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-divhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-divqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-divsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-divsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-extendhisi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-extendqisi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-extvsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-extzvsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixdfhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixdfqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixdfsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixsfhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixsfqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-fixsfsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-floatsisf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-insvsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-iorhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-iorqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-iorsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-mova.c: New test.
> 	* gcc.target/vax/cmpelim-eq-movdf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-movhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-movqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-movsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-movsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-muldf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-mulhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-mulqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-mulsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-mulsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-nothi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-notqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-notsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-rotlsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-rotrsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-subdf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-subhi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-subqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-subsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-subsi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-truncdfsf.c: New test.
> 	* gcc.target/vax/cmpelim-eq-trunchiqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-truncsihi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-truncsiqi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-zextendhisi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-zextendqihi.c: New test.
> 	* gcc.target/vax/cmpelim-eq-zextendqisi.c: New test.
> 	* gcc.target/vax/cmpelim-le-adddf.c: New test.
> 	* gcc.target/vax/cmpelim-le-addhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-addqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-addsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-addsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-andhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-andqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-andsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-ashlsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-ashrsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-divdf.c: New test.
> 	* gcc.target/vax/cmpelim-le-divhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-divqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-divsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-divsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-extendhisi.c: New test.
> 	* gcc.target/vax/cmpelim-le-extendqisi.c: New test.
> 	* gcc.target/vax/cmpelim-le-extvsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-extzvsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixdfhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixdfqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixdfsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixsfhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixsfqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-fixsfsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-floatsisf.c: New test.
> 	* gcc.target/vax/cmpelim-le-insvsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-iorhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-iorqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-iorsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-movdf.c: New test.
> 	* gcc.target/vax/cmpelim-le-movhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-movqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-movsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-movsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-muldf.c: New test.
> 	* gcc.target/vax/cmpelim-le-mulhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-mulqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-mulsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-mulsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-nothi.c: New test.
> 	* gcc.target/vax/cmpelim-le-notqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-notsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-rotlsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-rotrsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-subdf.c: New test.
> 	* gcc.target/vax/cmpelim-le-subhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-subqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-subsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-subsi.c: New test.
> 	* gcc.target/vax/cmpelim-le-truncdfsf.c: New test.
> 	* gcc.target/vax/cmpelim-le-xorhi.c: New test.
> 	* gcc.target/vax/cmpelim-le-xorqi.c: New test.
> 	* gcc.target/vax/cmpelim-le-xorsi.c: New test.
> 	* gcc.target/vax/cmpelim-leu-subhi.c: New test.
> 	* gcc.target/vax/cmpelim-leu-subqi.c: New test.
> 	* gcc.target/vax/cmpelim-leu-subsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-adddf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-addhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-addqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-addsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-addsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-andhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-andqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-andsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-ashlsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-ashrsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-divdf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-divhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-divqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-divsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-divsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-extendhisi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-extendqisi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-extvsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-extzvsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixdfhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixdfqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixdfsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixsfhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixsfqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-fixsfsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-floatsisf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-insvsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-iorhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-iorqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-iorsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-movdf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-movhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-movqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-movsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-movsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-muldf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-mulhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-mulqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-mulsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-mulsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-nothi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-notqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-notsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-rotlsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-rotrsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-subdf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-subhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-subqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-subsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-subsi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-truncdfsf.c: New test.
> 	* gcc.target/vax/cmpelim-lt-xorhi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-xorqi.c: New test.
> 	* gcc.target/vax/cmpelim-lt-xorsi.c: New test.
> 	* gcc.target/vax/cmpelim-ltu-subhi.c: New test.
> 	* gcc.target/vax/cmpelim-ltu-subqi.c: New test.
> 	* gcc.target/vax/cmpelim-ltu-subsi.c: New test.
> 	* gcc.target/vax/cmpelim-xx-addsi.c: New test.
> 	* gcc.target/vax/cmpelim-xx-insvsi.c: New test.
> 	* gcc.target/vax/cmpelim-xxu-subsi.c: New test.
> 	* gcc.target/vax/peephole2-eq-andhi.c: New test.
> 	* gcc.target/vax/peephole2-eq-andqi.c: New test.
> 	* gcc.target/vax/peephole2-eq-andsi.c: New test.
> 	* gcc.target/vax/peephole2-eq-cmpvsi.c: New test.
> 	* gcc.target/vax/peephole2-eq-cmpzvsi.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzhi-0.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzhi-1.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzqi-0.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzqi-1.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzsi-0.c: New test.
> 	* gcc.target/vax/peephole2-eq-ctzsi-1.c: New test.
> 	* gcc.target/vax/peephole2-eq-ffshi.c: New test.
> 	* gcc.target/vax/peephole2-eq-ffsqi.c: New test.
> 	* gcc.target/vax/peephole2-eq-ffssi.c: New test.
> 	* gcc.target/vax/peephole2-le-andhi.c: New test.
> 	* gcc.target/vax/peephole2-le-andqi.c: New test.
> 	* gcc.target/vax/peephole2-le-andsi.c: New test.
> 	* gcc.target/vax/peephole2-le-cmpvsi.c: New test.
> 	* gcc.target/vax/peephole2-le-cmpzvsi.c: New test.
> 	* gcc.target/vax/peephole2-leu-cmpvsi.c: New test.
> 	* gcc.target/vax/peephole2-leu-cmpzvsi.c: New test.
> 	* gcc.target/vax/peephole2-lt-andhi.c: New test.
> 	* gcc.target/vax/peephole2-lt-andqi.c: New test.
> 	* gcc.target/vax/peephole2-lt-andsi.c: New test.
> 	* gcc.target/vax/peephole2-lt-cmpvsi.c: New test.
> 	* gcc.target/vax/peephole2-lt-cmpzvsi.c: New test.
> 	* gcc.target/vax/peephole2-ltu-cmpvsi.c: New test.
> 	* gcc.target/vax/peephole2-ltu-cmpzvsi.c: New test.
Sweet.  OK once the prereqs are all ACK'd.
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators
  2020-11-20  3:34 ` [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators Maciej W. Rozycki
@ 2020-11-21  4:19   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:19 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> Add wide integer aka 'w' rtx format support to int iterators so that
> machine description can iterate over `const_int' expressions.
>
> This is made by expanding standard integer aka 'i' format support,
> observing that any standard integer already present in any of our
> existing RTL code will also fit into HOST_WIDE_INT, so there is no need
> for a separate handler.  Any truncation of the number parsed is made by
> the caller.  An assumption is made however that no place relies on
> capping out of range values to INT_MAX.
>
> Now the 'p' format is handled explicitly rather than being implied by
> rtx being a SUBREG, so actually assert that it is, just to play safe.
>
> 	gcc/
> 	* read-rtl.c: Add a page-feed separator at the start of iterator
> 	code.
> 	(struct iterator_group): Change the return type to HOST_WIDE_INT
> 	for the `find_builtin' member.  Likewise the second parameter
> 	type for the `apply_iterator' member.
> 	(atoll) [!HAVE_ATOQ]: Reorder.
> 	(find_mode, find_code): Change the return type to HOST_WIDE_INT.
> 	(apply_mode_iterator, apply_code_iterator)
> 	(apply_subst_iterator): Change the second parameter type to
> 	HOST_WIDE_INT.
> 	(find_int): Handle input suitable for HOST_WIDE_INT output.
> 	(apply_int_iterator): Rewrite in terms of explicit format
> 	interpretation.
> 	(rtx_reader::read_rtx_operand) <'w'>: Fold into...
> 	<'i', 'n', 'p'>: ... this.
> 	* doc/md.texi (Int Iterators): Document 'w' rtx format support.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE
  2020-11-20  3:34 ` [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE Maciej W. Rozycki
@ 2020-11-21  4:25   ` Jeff Law
  2020-12-03  3:50     ` [PATCH v2 " Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:25 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> VAX has interlocked branch instructions used for atomic operations and
> we want to have them wrapped in UNSPEC_VOLATILE so as not to have code
> carried across.  This however breaks with jump optimization and leads
> to an ICE in the build of libbacktrace like:
>
> .../libbacktrace/mmap.c:190:1: internal compiler error: in fixup_reorder_chain, at cfgrtl.c:3934
>   190 | }
>       | ^
> 0x1087d46b fixup_reorder_chain
> 	.../gcc/cfgrtl.c:3934
> 0x1087f29f cfg_layout_finalize()
> 	.../gcc/cfgrtl.c:4447
> 0x1087c74f execute
> 	.../gcc/cfgrtl.c:3662
>
> on RTL like:
>
> (jump_insn 18 17 150 4 (unspec_volatile [
>             (set (pc)
>                 (if_then_else (eq (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
>                             (const_int 1 [0x1])
>                             (const_int 0 [0]))
>                         (const_int 1 [0x1]))
>                     (label_ref 20)
>                     (pc)))
>             (set (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
>                     (const_int 1 [0x1])
>                     (const_int 0 [0]))
>                 (const_int 1 [0x1]))
>         ] 101) ".../libbacktrace/mmap.c":135:14 158 {jbbssisi}
>      (nil)
>  -> 20)
>
> when those branches are enabled with a follow-up change.  Also showing
> with:
>
> FAIL: gcc.dg/pr61756.c (internal compiler error)
>
> Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
> also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
> branches from being removed as they won't be accepted by `onlyjump_p',
> we just need to let them through.
>
> 	gcc/
> 	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
> 	UNSPEC_VOLATILE.
> 	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
I've got some concerns that there may be users of pc_set where handling
UNSPECs would be undesirable.  For example the uses in cfgcleanup.

Would it make sense to have the handling of UNSPECs be conditional so
that we don't get unexpected jump threading, cross jumping, etc?

jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins
  2020-11-20  3:35 ` [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins Maciej W. Rozycki
@ 2020-11-21  4:26   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21  4:26 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> Remove an ICE like:
>
> during RTL pass: expand
> .../libatomic/tas_n.c: In function 'libat_test_and_set_1':
> .../libatomic/tas_n.c:39:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1298
>    39 | }
>       | ^
> 0x108a09ff patch_jump_insn
> 	.../gcc/cfgrtl.c:1298
> 0x108a0b07 redirect_branch_edge
> 	.../gcc/cfgrtl.c:1325
> 0x108a124b rtl_redirect_edge_and_branch
> 	.../gcc/cfgrtl.c:1458
> 0x1087f6d3 redirect_edge_and_branch(edge_def*, basic_block_def*)
> 	.../gcc/cfghooks.c:373
> 0x11d6264b try_forward_edges
> 	.../gcc/cfgcleanup.c:562
> 0x11d6b0eb try_optimize_cfg
> 	.../gcc/cfgcleanup.c:2960
> 0x11d6ba4f cleanup_cfg(int)
> 	.../gcc/cfgcleanup.c:3174
> 0x10870b3f execute
> 	.../gcc/cfgexpand.c:6763
>
> triggered with an RTL pattern like:
>
> (jump_insn 8 7 20 2 (parallel [
>             (set (pc)
>                 (if_then_else (ne (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
>                             (const_int 1 [0x1])
>                             (const_int 0 [0]))
>                         (const_int 0 [0]))
>                     (label_ref 10)
>                     (pc)))
>             (set (zero_extract:SI (mem/v:QI (mem/f/c:SI (reg/f:SI 16 virtual-incoming-args) [1 mptr+0 S4 A32]) [-1  S1 A8])
>                     (const_int 1 [0x1])
>                     (const_int 0 [0]))
>                 (const_int 1 [0x1]))
>         ]) ".../libatomic/tas_n.c":38:12 -1
>      (nil)
>  -> 10)
>
> caused by a volatile memory reference used that is not accepted by the
> `memory_operand' predicate of the `jbbssiqi' insn explicitly referred
> from the `sync_lock_test_and_setqi' expander.  Also seen with:
>
> FAIL: gcc.dg/pr61756.c (internal compiler error)
>
> Define a new `any_memory_operand' predicate accepting both ordinary and
> volatile memory references and use it with the `jbb<ccss>i<mode>' insn,
> so as to address the ICE.
>
> Also remove useless operations from the `sync_lock_test_and_set<mode>'
> and `sync_lock_release<mode>' expanders as those always either complete
> or fail and therefore never fall through to using their template other
> than to match operands.  Wrap `jbb<ccss>i<mode>' into `unspec_volatile'
> instead so that the jump does not get removed or reordered.  Share one
> index to avoid a complication around the iterators since the index is
> nowhere referred to anyway and the pattern required pulled by its name.
>
> Test cases will be added separately.
>
> 	gcc/
> 	* config/vax/predicates.md (volatile_mem_operand)
> 	(any_memory_operand): New predicates.
> 	* config/vax/builtins.md (VUNSPEC_UNLOCK): Remove constant.
> 	(sync_lock_test_and_set<mode>): Remove `set' and `unspec'
> 	operations, match operands only.  Reformat.
> 	(sync_lock_release<mode>): Likewise.  Remove cruft.
> 	(jbb<ccss>i<mode>): Wrap into `unspec_volatile', use
> 	`any_memory_operand' predicate.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns
  2020-11-20  3:35 ` [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns Maciej W. Rozycki
@ 2020-11-21 17:01   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:01 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> It makes no sense for insn operand predicates, as long as they accept a
> register operand, to be more restrictive than the set of the associated
> constraints, because expand will choose the insn based on the relevant
> operand being a pseudo register then and reload keep it happily as a
> memory reference if a constraint permits it.  So the restriction posed
> by such a predicate will be happily ignored, and moreover if a splitter
> is added, such as required for MODE_CC support, the new instructions
> will reject the original operands supplied, causing an ICE.  An actual
> example will be given with a subsequent change.
>
> Remove such inconsistencies we have with the EXTV/EXTZV/INSV insns then,
> observing that a bitfield located in memory is byte-addressed by the
> respective machine instructions and therefore SImode may only be used
> with a register or an offsettable memory operand (i.e. not an indexed,
> pre-decremented, or post-incremented one), which has already been taken
> into account with the constraints currently used, except for `*insv_2'.
> The QI machine mode may be used for the bitfield location with any kind
> of memory operand, but we got the constraint wrong, although harmlessly
> in reality, with `*insv'.  Fix that for consistency though.
>
> Also give the insns names, for easier reference here and elsewhere.
>
> 	gcc/
> 	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
> 	(*extv_aligned, *extv_non_const, *extzv_non_const): Name insns.
> 	Fix location predicate.
> 	(*extzv): Name insn.
> 	(*insv): Likewise.  Fix location constraint.
> 	(*insv_2): Likewise, and the predicate.
OK.
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns
  2020-11-20  3:35 ` [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns Maciej W. Rozycki
@ 2020-11-21 17:03   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:03 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> With the `*insv_aligned', `*extzv_aligned' and `*extv_aligned' insns we
> are going to adjust the bitfield location if it is in memory, so only
> allow such location addresses that can be offset, excluding external
> symbol references in the PIC mode in particular.
>
> This fixes an ICE like:
>
> during RTL pass: final
> In file included from .../gcc/testsuite/gcc.dg/torture/vshuf-v16qi.c:11:
> .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc: In function 'test_13':
> .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:27:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
> .../gcc/testsuite/gcc.dg/torture/vshuf-16.inc:16:1: note: in expansion of macro 'T'
> .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:28:1: note: in expansion of macro 'TESTS'
> 0x10a34b33 change_address_1
> 	.../gcc/emit-rtl.c:2275
> 0x10a358af adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
> 	.../gcc/emit-rtl.c:2409
> 0x11d2505f output_97
> 	.../gcc/config/vax/vax.md:806
> 0x10adec4b get_insn_template(int, rtx_insn*)
> 	.../gcc/final.c:2070
> 0x10ae1c5b final_scan_insn_1
> 	.../gcc/final.c:3039
> 0x10ae2257 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
> 	.../gcc/final.c:3152
> 0x10ade9a3 final_1
> 	.../gcc/final.c:2020
> 0x10ae6157 rest_of_handle_final
> 	.../gcc/final.c:4658
> 0x10ae6697 execute
> 	.../gcc/final.c:4736
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.
> compiler exited with status 1
> FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)
>
> triggered by an RTL instruction like:
>
> (insn 97 96 98 (set (reg:SI 5 %r5 [88])
>         (zero_extract:SI (mem/c:SI (symbol_ref:SI ("b") <var_decl 0x7ffff7f801b0 b>) [0 b+0 S4 A128])
>             (const_int 8 [0x8])
>             (const_int 24 [0x18]))) ".../gcc/testsuite/gcc.dg/torture/vshuf-main.inc":28:1 97 {*extzv_aligned}
>      (nil))
>
> and removes these regressions:
>
> FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)
> FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (test for excess errors)
> FAIL: gcc.dg/torture/vshuf-v4hi.c   -O2  (internal compiler error)
> FAIL: gcc.dg/torture/vshuf-v4hi.c   -O2  (test for excess errors)
> FAIL: gcc.dg/torture/vshuf-v8hi.c   -O2  (internal compiler error)
> FAIL: gcc.dg/torture/vshuf-v8hi.c   -O2  (test for excess errors)
> FAIL: gcc.dg/torture/vshuf-v8qi.c   -O2  (internal compiler error)
> FAIL: gcc.dg/torture/vshuf-v8qi.c   -O2  (test for excess errors)
>
> However expand typically presents pseudo-registers rather than memory
> references to these insns, so a further rework is required to make a
> better use of the code variant they are supposed to produce.  This at
> least fixes the problem at hand.
>
> 	gcc/
> 	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
> 	(*extv_aligned): Also make sure the memory address of a bitfield
> 	location can be adjusted in the PIC mode.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns
  2020-11-20  3:35 ` [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns Maciej W. Rozycki
@ 2020-11-21 17:25   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:25 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> The INSV machine instruction is the only computational operation in the
> VAX ISA that keeps condition codes intact.  In preparation to MODE_CC
> transition keep patterns apart then that make or do not make use of said
> instruction.  For consistency update EXTV and EXTZV instruction uses
> accordingly.  In expand SUBREGs will be presented as operands, so handle
> that possibility in the insn condition.
>
> This actually yields better code by avoiding EXTV/EXTZV instructions in
> pseudo-aligned register cases previously resorting to those instructions:
>
> @@ -42,7 +42,7 @@ ins8:
>  	subl2 $4,%sp	# 21	[c=32]  addsi3
>  	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
>  	movl 8(%ap),%r1	# 17	[c=16]  movsi_2
> -	insv %r1,$8,$8,%r0	# 9	[c=4]  *insv_aligned
> +	insv %r1,$8,$8,%r0	# 9	[c=4]  *insv_2
>  	ret		# 25	[c=0]  return
>  	.size	ins8, .-ins8
>  	.align 1
> @@ -60,12 +60,12 @@ ext8:
>  .globl extz8
>  	.type	extz8, @function
>  extz8:
> -	.word 0	# 19	[c=0]  procedure_entry_mask
> -	subl2 $4,%sp	# 20	[c=32]  addsi3
> +	.word 0	# 18	[c=0]  procedure_entry_mask
> +	subl2 $4,%sp	# 19	[c=32]  addsi3
>  	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
> -	extzv $8,$8,%r0,%r1	# 13	[c=60]  *extzv_aligned
> -	movl %r1,%r0	# 18	[c=4]  movsi_2
> -	ret		# 24	[c=0]  return
> +	rotl $24,%r0,%r0	# 13	[c=60]  *extzv_non_const
> +	movzbl %r0,%r0
> +	ret		# 23	[c=0]  return
>  	.size	extz8, .-extz8
>  	.align 1
>  .globl ins16
> @@ -75,7 +75,7 @@ ins16:
>  	subl2 $4,%sp	# 21	[c=32]  addsi3
>  	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
>  	movl 8(%ap),%r1	# 17	[c=16]  movsi_2
> -	insv %r1,$16,$16,%r0	# 9	[c=4]  *insv_aligned
> +	insv %r1,$16,$16,%r0	# 9	[c=4]  *insv_2
>  	ret		# 25	[c=0]  return
>  	.size	ins16, .-ins16
>  	.align 1
> @@ -94,8 +94,9 @@ ext16:
>  extz16:
>  	.word 0	# 18	[c=0]  procedure_entry_mask
>  	subl2 $4,%sp	# 19	[c=32]  addsi3
> -	movl 4(%ap),%r1	# 2	[c=16]  movsi_2
> -	extzv $16,$16,%r1,%r0	# 7	[c=60]  *extzv_aligned
> +	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
> +	rotl $16,%r0,%r0	# 7	[c=60]  *extzv_non_const
> +	movzwl %r0,%r0
>  	movzwl %r0,%r0	# 13	[c=4]  zero_extendhisi2
>  	ret		# 23	[c=0]  return
>  	.size	extz16, .-extz16
>
> demonstrated with this program:
>
> typedef struct
> {
>   int f0:1;
>   int f1:7;
>   int f8:8;
>   int f16:16;
> } bit_t;
>
> typedef struct
> {
>   unsigned int f0:1;
>   unsigned int f1:7;
>   unsigned int f8:8;
>   unsigned int f16:16;
> } ubit_t;
>
> typedef union
> {
>   bit_t b;
>   int i;
> } bit_u;
>
> typedef union
> {
>   ubit_t b;
>   unsigned int i;
> } ubit_u;
>
> int
> ins1 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f1 = y;
>   return x.i;
> }
>
> int
> ext1 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> unsigned int
> extz1 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> int
> ins8 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f8 = y;
>   return x.i;
> }
>
> int
> ext8 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> unsigned int
> extz8 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> int
> ins16 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f16 = y;
>   return x.i;
> }
>
> int
> ext16 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> unsigned int
> extz16 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> It also papers over a regression:
>
> FAIL: gcc.dg/pr83623.c (internal compiler error)
> FAIL: gcc.dg/pr83623.c (test for excess errors)
>
> from an ICE like:
>
> during RTL pass: final
> .../gcc/testsuite/gcc.dg/pr83623.c: In function 'foo':
> .../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
> 0x10a056e3 change_address_1
> 	.../gcc/emit-rtl.c:2275
> 0x10a0645f adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
> 	.../gcc/emit-rtl.c:2409
> 0x11cb588f output_97
> 	.../gcc/config/vax/vax.md:808
> 0x10aafb2f get_insn_template(int, rtx_insn*)
> 	.../gcc/final.c:2070
> 0x10ab2b3f final_scan_insn_1
> 	.../gcc/final.c:3039
> 0x10ab313b final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
> 	.../gcc/final.c:3152
> 0x10aaf887 final_1
> 	.../gcc/final.c:2020
> 0x10ab703b rest_of_handle_final
> 	.../gcc/final.c:4658
> 0x10ab757b execute
> 	.../gcc/final.c:4736
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.
> compiler exited with status 1
> FAIL: gcc.dg/pr83623.c (internal compiler error)
>
> triggered by an RTL instruction like:
>
> (insn 17 14 145 (set (reg:SI 1 %r1)
>         (zero_extract:SI (mem/c:SI (symbol_ref:SI ("x") <var_decl 0x7ffff7f80120 x>) [1 x+0 S4 A128])
>             (const_int 16 [0x10])
>             (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/pr83623.c":12:9 97 {*extzv_aligned}
>      (nil))
>
> (where the address cannot be adjusted by 2 for PIC code as requested
> here as it would create an offset external symbol reference) otherwise
> caused by the patterns modified here, addressed next.  This indicates
> a further rework is warranted here, but at least problems at hand have
> been fixed.
>
> 	gcc/
> 	* config/vax/vax.md (*insv_aligned, *extzv_aligned)
> 	(*extv_aligned): Reject register bitfield locations that are not
> 	aligned to the least significant bit; update output statement
> 	accordingly.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations
  2020-11-20  3:36 ` [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations Maciej W. Rozycki
@ 2020-11-21 17:26   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:26 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> We have matching insns defined for `sign_extract' and `zero_extract'
> expressions, so make the three named patterns for bitfield operations
> consistent and make `extv' an expander rather than an insn taking a
> SImode, a QImode, and a SImode general operand for the LOC, SIZE, and
> POS operands respectively, like with the `extzv' and `insv' patterns,
> matching the machine instructions and giving the middle end more choice
> as to which actual insn to choose in a given situation.
>
> Given this program:
>
> typedef struct
> {
>   int f0:1;
>   int f1:7;
>   int f8:8;
>   int f16:16;
> } bit_t;
>
> typedef struct
> {
>   unsigned int f0:1;
>   unsigned int f1:7;
>   unsigned int f8:8;
>   unsigned int f16:16;
> } ubit_t;
>
> typedef union
> {
>   bit_t b;
>   int i;
> } bit_u;
>
> typedef union
> {
>   ubit_t b;
>   unsigned int i;
> } ubit_u;
>
> int
> ins1 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f1 = y;
>   return x.i;
> }
>
> int
> ext1 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> unsigned int
> extz1 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> int
> ins8 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f8 = y;
>   return x.i;
> }
>
> int
> ext8 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> unsigned int
> extz8 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> int
> ins16 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f16 = y;
>   return x.i;
> }
>
> int
> ext16 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> unsigned int
> extz16 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> this results in the following code change:
>
> @@ -16,12 +16,12 @@ ins1:
>  .globl ext1
>  	.type	ext1, @function
>  ext1:
> -	.word 0	# 19	[c=0]  procedure_entry_mask
> -	subl2 $4,%sp	# 20	[c=32]  addsi3
> +	.word 0	# 18	[c=0]  procedure_entry_mask
> +	subl2 $4,%sp	# 19	[c=32]  addsi3
>  	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
> -	cvtbl %r0,%r0	# 7	[c=4]  extendqisi2
> -	ashl $-1,%r0,%r0	# 14	[c=40]  *vax.md:624
> -	ret		# 24	[c=0]  return
> +	extv $1,$7,%r0,%r0	# 7	[c=60]  *extv_non_const
> +	cvtbl %r0,%r0	# 13	[c=4]  extendqisi2
> +	ret		# 23	[c=0]  return
>  	.size	ext1, .-ext1
>  	.align 1
>  .globl extz1
> @@ -49,12 +49,12 @@ ins8:
>  .globl ext8
>  	.type	ext8, @function
>  ext8:
> -	.word 0	# 20	[c=0]  procedure_entry_mask
> -	subl2 $4,%sp	# 21	[c=32]  addsi3
> +	.word 0	# 18	[c=0]  procedure_entry_mask
> +	subl2 $4,%sp	# 19	[c=32]  addsi3
>  	movl 4(%ap),%r0	# 2	[c=16]  movsi_2
> -	cvtwl %r0,%r0	# 7	[c=4]  extendhisi2
> -	ashl $-8,%r0,%r0	# 15	[c=40]  *vax.md:624
> -	ret		# 25	[c=0]  return
> +	rotl $24,%r0,%r0	# 13	[c=60]  *extv_non_const
> +	cvtbl %r0,%r0
> +	ret		# 23	[c=0]  return
>  	.size	ext8, .-ext8
>  	.align 1
>  .globl extz8
>
> If there is a performance degradation with the replacement sequences,
> then it can and should be sorted within `extv_non_const'.
>
> 	gcc/
> 	* config/vax/vax.md (extv): Rename insn to...
> 	(*extv): ... this.
> 	(extv): New expander.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns
  2020-11-20  3:36 ` [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns Maciej W. Rozycki
@ 2020-11-21 17:27   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:27 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> It makes no sense for insn operand predicates, as long as they accept a
> register operand, to be more restrictive than the set of the associated
> constraints, because expand will choose the insn based on the relevant
> operand being a pseudo register then and reload keep it happily as a
> memory reference if a constraint permits it.  So the restriction posed
> by such a predicate will be happily ignored, and moreover if a splitter
> is added, such as required for MODE_CC support, the new instructions
> will reject the original operands supplied, causing an ICE.  An actual
> example will be given with a subsequent change.
>
> Therefore, similarly to EXTV/EXTZV/INSV insns, remove inconsistencies
> with predicates and constraints of bitfield comparison insns, observing
> that a bitfield located in memory is byte-addressed by the respective
> machine instructions and therefore SImode may only be used with a
> register or an offsettable memory operand (i.e. not an indexed,
> pre-decremented, or post-incremented one).
>
> Also give the insns names, for easier reference here and elsewhere.
>
> 	gcc/
> 	* config/vax/vax.md (*cmpv_2): Name insn.
> 	(*cmpv, *cmpzv, *cmpzv_2): Likewise.  Fix location predicate and
> 	constraint.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx
  2020-11-20  3:36 ` [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx Maciej W. Rozycki
@ 2020-11-21 17:29   ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-21 17:29 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> The use of a constant double zero is required for post-reload compare
> elimination to be able to discard redundant floating-point comparisons,
> for example with a VAX RTL instruction stream like:
>
> (insn 34 4 3 2 (parallel [
>             (set (reg/v:DF 0 %r0 [orig:24 x ] [24])
>                 (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
>                         (const_int 4 [0x4])) [1 x+0 S8 A32]))
>             (clobber (reg:CC 16 %psl))
>         ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 37 {*movdf}
>      (nil))
> (note 3 34 35 2 NOTE_INSN_FUNCTION_BEG)
> (insn 35 3 36 2 (set (reg:CCZ 16 %psl)
>         (compare:CCZ (reg/v:DF 0 %r0 [orig:24 x ] [24])
>             (const_double:DF 0.0 [0x0.0p+0]))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 21 {*cmpdf_ccz}
>      (nil))
> (jump_insn 36 35 9 2 (set (pc)
>         (if_then_else (eq (reg:CCZ 16 %psl)
>                 (const_int 0 [0]))
>             (label_ref 11)
>             (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz}
>      (int_list:REG_BR_PROB 536870916 (nil))
>  -> 11)
>
> that we want to transform into:
>
> (insn 34 4 3 2 (parallel [
>             (set (reg:CCZ 16 %psl)
>                 (compare:CCZ (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
>                             (const_int 4 [0x4])) [1 x+0 S8 A32])
>                     (const_double:DF 0.0 [0x0.0p+0])))
>             (set (reg/v:DF 0 %r0 [orig:24 x ] [24])
>                 (mem/c:DF (plus:SI (reg/f:SI 12 %ap)
>                         (const_int 4 [0x4])) [1 x+0 S8 A32]))
>         ]) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":9:1 40 {*movdf_ccz}
>      (nil))
> (note 3 34 36 2 NOTE_INSN_FUNCTION_BEG)
> (jump_insn 36 3 9 2 (set (pc)
>         (if_then_else (eq (reg:CCZ 16 %psl)
>                 (const_int 0 [0]))
>             (label_ref 11)
>             (pc))) ".../gcc/testsuite/gcc.target/vax/cmpelim-eq-movdf.c":10:6 537 {*branch_ccz}
>      (int_list:REG_BR_PROB 536870916 (nil))
>  -> 11)
>
> with the upcoming MODE_CC representation.
>
> For this we need to express the `const_double:DF 0.0 [0x0.0p+0]' rtx as
> recorded above in the relevant pattern(s) in machine description.  The
> way we represent double constants, as a host-dependent number of wide
> integers, however means that we currently have no portable way to encode
> a double zero constant in machine description.
>
> Define a syntactic rtx alias then to represent `(const_double 0 0 ...)'
> as if the suitable number of zeros have been supplied according to the
> host-specific definition of CONST_DOUBLE_FORMAT.
>
> 	gcc/
> 	* read-rtl.c (rtx_reader::read_rtx_code): Handle syntactic
> 	`const_double_zero' rtx.
> 	* doc/rtl.texi (Constant Expression Types): Document it.
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (31 preceding siblings ...)
  2020-11-20  7:58 ` [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Anders Magnusson
@ 2020-11-21 21:02 ` Toon Moene
  2020-11-23 21:51   ` Maciej W. Rozycki
  2020-11-23 15:48 ` Paul Koning
  2020-11-25 18:36 ` Maciej W. Rozycki
  34 siblings, 1 reply; 117+ messages in thread
From: Toon Moene @ 2020-11-21 21:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: fortran

[ cc'd to the fortran mailing list to hopely get some more knowledgeable 
input ... ]

On 11/20/20 4:38 AM, Maciej W. Rozycki wrote:

> 2. libgfortran -- oddly enough for Fortran a piece requires IEEE 754
>     floating-point arithmetic (possibly a porting problem too).

gcc/libgfortran/config.h.in does have:

/* Define to 1 if you have the <ieeefp.h> header file. */
#undef HAVE_IEEEFP_H

So perhaps it does do the "right thing" if you do not have this header 
file on your VAX operating system.

The Fortran Standard allows an implementation *not* to have IEEE 
floating point support ...

Kind regards,

-- 
Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation
  2020-11-20  3:36 ` [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation Maciej W. Rozycki
@ 2020-11-22  3:27   ` Jeff Law
  2020-12-09 16:09   ` Maciej W. Rozycki
  1 sibling, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-22  3:27 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson, Paul Koning, Matt Thomas



On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> In the VAX ISA INSV bitfield insert instruction is the only computational
> operation that keeps the condition codes, held in the PSL or Processor
> Status Longword register, intact.  The instruction is flexible enough it
> could potentially be used for data moves post-reload, but then reportedly
> it is not the best choice performance-wise, and then we have no addition
> operation available that would keep the condition codes unchanged.
>
> Futhermore, as usually with a complex CISC ISA, for many operations we
> have several machine instructions or instruction sequences to choose
> from that set condition codes in a different manner.
>
> Use the approach then where the condition codes only get introduced by
> reload, by definining instruction splitters for RTL insns that change
> condition codes in some way, by default considering them clobbered.
>
> Then to prevent code generated from regressing too much provide insns
> that include a `compare' operation setting the condition codes in
> parallel to the main operation.  The manner condition codes are set by
> each insn is supposed to be provided by the whatever the SELECT_CC_MODE
> macro expands to.
>
> Given that individual patterns provided for the same RTL basic operation
> may set the condion codes differently keeping the information away from
> the insn patterns themselves would cause a maintenance nightmare and
> would be bound to fail in a horrible way sooner or later.  Therefore
> instead let the patterns themselves choose which condition modes they
> support, by having one or more subst iterators applied and then have
> individual comparison operators require the specific condition mode each
> according to the codes used by the operation.
>
> While subst iterators only support one alternative each, there is
> actually no problem with applying multiple ones to a single insn with
> the result as intended, and if the corresponding subst attribute
> supplies an empty NO-SUBST-VALUE, then no mess results even.  Make use
> of this observation.
>
> Add appropriate subst iterators to all the computational patterns then,
> according to the condition codes they usably set, including DImode ones
> and a substitute DImode comparison instruction in the absence of a CMPQ
> machine instruction, however do not provide a `cbranchdi4' named pattern
> as without a further development it regresses code quality by resorting
> to the `__cmpdi2' libcall where a simpler operation would do, e.g. to
> check for negativity the TSTL machine instruction may be executed over
> the upper longword only.  This is good material for further work.
>
> Do not apply subst iterators to the increment- or decrement-and-branch
> patterns at this time; these may yet have to be reviewed, in particular
> whether `*jsobneq_minus_one' is still relevant in the context of the
> recent integer constant cost review.
>
> Also add a couple of peepholes to help eliminating comparisons in some
> problematic cases, such as with the BIT instruction which is bitwise-AND
> for condition codes only that has no direct counterpart for the actual
> calculation, because the BIC instruction which does do bitwise-AND and
> produces a result implements the operation with a bitwise negation of
> its input `mask' operand.  Or the FFS instruction which sets the Z
> condition code according to its `field' input operand rather than the
> result produced.  Or the bitfield comparisons we don't have generic
> middle-end support for.
>
> Code size stats are as follows, obtained from 17640 and 9086 executables
> built in `check-c' and `check-c++' GCC testing respectively:
>
>                       check-c                 check-c++
>               samples average  median  samples average  median
> ---------------------------------------------------------------
> regressions      1813  0.578%  0.198%      289  0.349%  0.175%
> unchanged       15160  0.000%  0.000%     8662  0.000%  0.000%
> progressions      667 -0.589% -0.194%      135 -0.944% -0.191%
> ----------------------------------------------------------------
> total           17640  0.037%  0.000%     9086 -0.003%  0.000%
>
> Outliers:
>
> old     new     change  %change filename
> ----------------------------------------------------
> 2406    2950    +544    +22.610 20111208-1.exe
> 4314    5329    +1015   +23.528 pr39417.exe
> 2235    3055    +820    +36.689 990404-1.exe
> 2631    4213    +1582   +60.129 pr57521.exe
> 3063    5579    +2516   +82.142 20000422-1.exe
>
> and:
>
> old     new     change  %change filename
> ----------------------------------------------------
> 6317    4845    -1472   -23.302 vector-compare-1.exe
> 6313    4845    -1468   -23.254 vector-compare-1.exe
> 6474    5002    -1472   -22.737 vector-compare-1.exe
> 6470    5002    -1468   -22.689 vector-compare-1.exe
>
> We have some code quality regressions like:
>
>     10861:	9e ef d9 12 	movab 11b40 <p>,r0
>     10865:	00 00 50
>     10868:	90 a0 03 a0 	movb 0x3(r0),0x2(r0)
>     1086c:	02
>     1086d:	d1 60 8f 61 	cmpl (r0),$0x64646261
>     10871:	62 64 64
>     10874:	13 07 		beql 1087d <main_test+0x21>
>
> to:
>
>     10861:	9e ef e1 12	movab 11b48 <p>,r0
>     10865:	00 00 50
>     10868:	90 a0 03 a0 	movb 0x3(r0),0x2(r0)
>     1086c:	02
>     1086d:	d1 ef d5 12 	cmpl 11b48 <p>,$0x64646261
>     10871:	00 00 8f 61
>     10875:	62 64 64
>     10878:	13 07 		beql 10881 <main_test+0x25>
>
> (from `memmove-2.x2') due to the constant propagation passes eagerly
> replacing pseudo registers with direct symbol references where possible,
> which does not happen with CC0 even though the passes do run regardless.
>
> There are further code quality regressions due to earlier compilation
> stages trying to push expression evaluation earlier where possible so
> as to make data dependencies further apart from each other.  This works
> well for computations and architectures that do not involve condition
> codes set as a side effect of calculations.  However for integer
> negation that makes assembly code produced like:
>
> 	movb *8(%ap),%r0
> 	mnegb %r0,%r1
> 	tstb %r0
> 	jeql .L2
>
> the RTL equibvalent of which the comparison elimination pass cannot
> really do anything about, because the comparison is made on the source
> rather than the target operand of the negation (we could add a peephole
> for this, but this seems futile an effort, as one'd have to iterate over
> all the possible such cases), even though this is really equivalent to:
>
> 	movb *8(%ap),%r0
> 	mnegb %r0,%r1
> 	jeql .L2
>
> or, if R0 is dead at the conclusion of the branch, even:
>
> 	mnegb *8(%ap),%r1
> 	jeql .L2
>
> Since the compiler insists on doing the comparison on the source of the
> negation it obviously has to load it into a temporary so as to avoid
> accessing the original memory location twice, hence the sequence of
> three instructions rather than just a single one.  A similar phenomenon
> can be observed with the XOR operation and in other cases.
>
> In some cases a comparison does get eliminated, however useless moves
> into registers done in preparation to it remain, such as with:
>
> 	movb *8(%ap),%r2
> 	movb *12(%ap),%r1
> 	subb3 %r1,%r2,%r0
> 	jlssu .L2
>
> where R1 and R2 are both dead at conclusion and therefore:
>
> 	subb3 *12(%ap),*8(%ap),%r0
> 	jlssu .L2
>
> would obviously do, but there was to be a comparison before the branch:
>
> 	cmpb %r2,%r1
>
> All this looks like material for future improvement.
>
> Test cases for comparison elimination and the peepholes will be supplied
> separately.
>
> 	gcc/
> 	PR target/95294
> 	* config/vax/elf.h (REGISTER_NAMES): Append `%psl'.
> 	* config/vax/vax-modes.def (CCN, CCNZ, CCZ): New modes.
> 	* config/vax/vax-protos.h (vax_select_cc_mode): New prototype.
> 	(vax_maybe_split_dimode_move): Likewise.
> 	(vax_notice_update_cc): Remove prototype.
> 	* config/vax/vax.c (TARGET_FLAGS_REGNUM): New macro.
> 	(TARGET_CC_MODES_COMPATIBLE): Likewise.
> 	(TARGET_MD_ASM_ADJUST): Likewise.
> 	(vax_select_cc_mode): New function
> 	(vax_cc_modes_compatible): Likewise.
> 	(vax_md_asm_adjust): Likewise.
> 	(vax_notice_update_cc): Remove function.
> 	(vax_output_int_move): Factor out code checking if a DImode move
> 	may have to be split...
> 	(vax_maybe_split_dimode_move): ... into this new function.
> 	* config/vax/vax.h (FIRST_PSEUDO_REGISTER): Bump up.
> 	(FIXED_REGISTERS): Append an entry for PSL.
> 	(CALL_USED_REGISTERS): Likewise.
> 	(NOTICE_UPDATE_CC, OUTPUT_JUMP): Remove macros.
> 	(SELECT_CC_MODE): New macro.
> 	(REGISTER_NAMES): Append `psl'.
> 	* config/vax/predicates.md (const_zero_operand)
> 	(vax_cc_comparison_operator, vax_ccn_comparison_operator)
> 	(vax_ccnz_comparison_operator, vax_ccz_comparison_operator):
> 	New predicates.
> 	* config/vax/builtins.md: Rewrite for MODE_CC representation.
> 	* config/vax/vax.md: Likewise.
So I just spot-checked this and the bits I looked at were quite sane. 
Given that and the fact that the port is on the chopping block if we
don't get the conversion done, I think it is fine to ACK this now and if
we want to iterate on things further we certainly can.

Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (32 preceding siblings ...)
  2020-11-21 21:02 ` Toon Moene
@ 2020-11-23 15:48 ` Paul Koning
  2020-11-25 17:07   ` Maciej W. Rozycki
  2020-11-25 18:36 ` Maciej W. Rozycki
  34 siblings, 1 reply; 117+ messages in thread
From: Paul Koning @ 2020-11-23 15:48 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: GCC Patches, Jeff Law



> On Nov 19, 2020, at 10:38 PM, Maciej W. Rozycki <macro@linux-mips.org> wrote:
> 
> Hi,
> 
> [Paul, there's a PDP11 piece for you further down here and then 29/31.]
> 
> ...
> 
> Then there is a fix for the PDP11 backend addressing an issue I found in 
> the handling of floating-point comparisons.  Unlike all the other changes 
> this one has not been regression-tested, not even built as I have no idea 
> how to prepare a development environment for a PDP11 target (also none of 
> my VAX pieces is old enough to support PDP11 machine code execution).

I agree this is a correct change, interesting that it was missed before.  You'd expect some ICE issues from that mistake.  Perhaps there were and I didn't realize the cause; the PDP11 test run is not yet fully clean.

I've hacked together a primitive newlib based "bare metal" execution test setup that uses SIMH, but it's not a particularly clean setup.  And it hasn't been posted, I hope to be able to do that at some point.

Thanks for the fix.

	paul


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-20  7:58 ` [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Anders Magnusson
@ 2020-11-23 20:31   ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-23 20:31 UTC (permalink / raw)
  To: Anders Magnusson; +Cc: gcc-patches, Jeff Law, Paul Koning, Matt Thomas

On Fri, 20 Nov 2020, Anders Magnusson wrote:

> >   Then there is a fix for the PDP11 backend addressing an issue I found in
> > the handling of floating-point comparisons.  Unlike all the other changes
> > this one has not been regression-tested, not even built as I have no idea
> > how to prepare a development environment for a PDP11 target (also none of
> > my VAX pieces is old enough to support PDP11 machine code execution).
> You could use simh /w 2.11BSD, or if you want to test it on real hardware I
> have a 11/83 where you could test?

 This promises a lot of fun, but regrettably I think I cannot afford the 
time required to get this set up right now.  And getting at a piece of 
hardware, real or simulated, is the least of the problem here.  Getting a 
proper cross-compilation environment set up is, as Paul's recent response 
also indicates.  And to verify this change it is all that is needed really 
(though running full testing never hurts).

 Running testing across the Internet, while supported by DejaGNU, even (or 
maybe especially) if all the security issues around it have been sorted is 
going to be terribly slow.  And having peeked at the PDP-11 compatibility 
chapter of the VAX 032 spec I note that it does not actually include FPU 
emulation, so it would have to be a real PDP-11 piece anyway.

 Anyway once the patches have been merged, which given all the approvals 
from Jeff I think is going to take until verification completes by the end 
of this week, I need to move on.

 First I need to figure out why an attempt to use a DEFPA FDDI network 
interface with my brand new POWER9 system makes the system firmware spew a 
flood of warning messages on the main console (there's the BMC console as 
well) and the interface fails to initialise and work; the MAC address is 
retrieved as all-zeros.  I only brought the system up enough to complete 
this effort and I need to complete the rest while I'm onsite (owing to the 
pandemic).

 NB as a precaution to anyone considering to use POWER9 for software 
development: I have learnt the hard way with this very VAX/GCC effort of 
one embarassing shortcoming of the architecture when it comes to this kind 
of use.  It only implements a lone single hardware watchpoint, and then a 
security-impared one, which therefore has to be force-enabled (with Linux 
anyway) before it can be used (cf. Documentation/powerpc/dawr-power9.rst 
in Linux sources).  Consequently I had to take extra care not to have more 
then one watchpoint set at any given time or GDB would resort to using 
software watchpoints, painfully slow.

 I used to think watchpoints are for granted nowadays and before getting 
this system I didn't even think such a silly shortcoming would be possible 
in 2020 with a performance chip where the cost of a couple watchpoints is 
nothing in terms of silicon.  I mean Intel x86 has had *four* of them as 
standard since 1985(!) in every single even most crippled implementation, 
and myself I have used this feature since 1991.  And even embedded chips 
such as MIPS ones usually have at least two these days.

 Based on my quick research this shortcoming has now been corrected with 
POWER10, but I find the 35 years required to get on par with x86 a bit 
disappointing, and of course I won't be able to make use of it anyway.

 Second I need to find a new day job.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-21 21:02 ` Toon Moene
@ 2020-11-23 21:51   ` Maciej W. Rozycki
  2020-11-23 22:12     ` Thomas Koenig
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-23 21:51 UTC (permalink / raw)
  To: Toon Moene; +Cc: gcc-patches, fortran

On Sat, 21 Nov 2020, Toon Moene wrote:

> > 2. libgfortran -- oddly enough for Fortran a piece requires IEEE 754
> >     floating-point arithmetic (possibly a porting problem too).
> 
> gcc/libgfortran/config.h.in does have:
> 
> /* Define to 1 if you have the <ieeefp.h> header file. */
> #undef HAVE_IEEEFP_H
> 
> So perhaps it does do the "right thing" if you do not have this header file on
> your VAX operating system.

 Well it does not:

In file included from .../libgfortran/generated/maxval_r4.c:26:
.../libgfortran/generated/maxval_r4.c: In function 'maxval_r4':
.../libgfortran/libgfortran.h:292:30: warning: target format does not support infinity
  292 | # define GFC_REAL_4_INFINITY __builtin_inff ()
      |                              ^~~~~~~~~~~~~~
.../libgfortran/generated/maxval_r4.c:149:19:
note: in expansion of macro 'GFC_REAL_4_INFINITY'
  149 |         result = -GFC_REAL_4_INFINITY;
      |                   ^~~~~~~~~~~~~~~~~~~
.../libgfortran/generated/maxval_r4.c: In function 'mmaxval_r4':
.../libgfortran/libgfortran.h:292:30: warning: target format does not support infinity
  292 | # define GFC_REAL_4_INFINITY __builtin_inff ()
      |                              ^~~~~~~~~~~~~~
.../libgfortran/generated/maxval_r4.c:363:19:
note: in expansion of macro 'GFC_REAL_4_INFINITY'
  363 |         result = -GFC_REAL_4_INFINITY;
      |                   ^~~~~~~~~~~~~~~~~~~
{standard input}: Assembler messages:
{standard input}:204: Fatal error: Can't relocate expression
make[3]: *** [Makefile:3358: maxval_r4.lo] Error 1

with the offending assembly instruction at 204 being:

	movf $0f+QNaN,%r2

and the `QNaN' part of the operand being what GAS complains about (of 
course it is a problem too that GCC lets the infinity intrinsics through 
with a mere warning and rubbish emitted rather than bailing out right 
away, but they are not supposed to be requested in the first place as the 
notion of infinity is specific to IEEE 754 FP and the VAX FP format used 
here does not support such an FP datum).

 The absence of IEEE 754 FP is correctly recognised by the configuration 
script:

checking for ieeefp.h... no
[...]
configure: FPU dependent file will be fpu-generic.h
configure: Support for IEEE modules: no

> The Fortran Standard allows an implementation *not* to have IEEE floating
> point support ...

 Given how long before IEEE 754 Fortran was invented I would be rather 
surprised if it was the other way round, which is why I have suspected, as 
I have noted in the piece quoted above, a problem with the VAX/NetBSD port 
of libgfortran.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-23 21:51   ` Maciej W. Rozycki
@ 2020-11-23 22:12     ` Thomas Koenig
  2020-11-24  4:28       ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Thomas Koenig @ 2020-11-23 22:12 UTC (permalink / raw)
  To: Maciej W. Rozycki, Toon Moene; +Cc: gcc-patches, fortran

Am 23.11.20 um 22:51 schrieb Maciej W. Rozycki:
>> /* Define to 1 if you have the <ieeefp.h> header file. */
>> #undef HAVE_IEEEFP_H
>>
>> So perhaps it does do the "right thing" if you do not have this header file on
>> your VAX operating system.
>   Well it does not:
> 
> In file included from .../libgfortran/generated/maxval_r4.c:26:
> .../libgfortran/generated/maxval_r4.c: In function 'maxval_r4':
> .../libgfortran/libgfortran.h:292:30: warning: target format does not support infinity
>    292 | # define GFC_REAL_4_INFINITY __builtin_inff ()
>        |                              ^~~~~~~~~~~~~~

This is guarded with

#ifdef __FLT_HAS_INFINITY__
# define GFC_REAL_4_INFINITY __builtin_inff ()
#endif

I don't know how or why __FLT_HAS_INFINITY is set for a target which
does not support it, but if you get rid of that macro, that particular
problem should be solved.

Best regards

	Thomas

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 02/31] VAX: Remove `c' operand format specifier overload
  2020-11-20  3:34 ` [PATCH 02/31] VAX: Remove `c' operand format specifier overload Maciej W. Rozycki
  2020-11-20 23:16   ` Jeff Law
@ 2020-11-24  1:12   ` Segher Boessenkool
  1 sibling, 0 replies; 117+ messages in thread
From: Segher Boessenkool @ 2020-11-24  1:12 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson

On Fri, Nov 20, 2020 at 03:34:16AM +0000, Maciej W. Rozycki wrote:
> The `c' operand format specifier is handled directly by the middle end
> in `output_asm_insn':
> 
>    %cN means require operand N to be a constant
>       and print the constant expression with no punctuation.
> 
> however it resorts to the target for constants that are not valid
> addresses:
> 
> 	    else if (letter == 'c')
> 	      {
> 		if (CONSTANT_ADDRESS_P (operands[opnum]))
> 		  output_addr_const (asm_out_file, operands[opnum]);
> 		else
> 		  output_operand (operands[opnum], 'c');
> 	      }
> 
> The VAX backend expects the fallback never to happen and overloads `c'
> with the branch condition code.  This is confusing however

There are 16 targets in trunk that overload the 'c' output modifier.
Most do it for something with condition codes (or comparisons).  This is
a well-established convention, confusing or not :-)

(I have nothing against the patch of course.)


Segher

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent
  2020-11-20  3:36 ` [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Maciej W. Rozycki
  2020-11-21  4:06   ` Jeff Law
@ 2020-11-24  1:37   ` Segher Boessenkool
  1 sibling, 0 replies; 117+ messages in thread
From: Segher Boessenkool @ 2020-11-24  1:37 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson

On Fri, Nov 20, 2020 at 03:36:24AM +0000, Maciej W. Rozycki wrote:
> Use a double colon to introduce the comments like elsewhere throughout
> the VAX machine description.

It's a double semicolon, so kind of a single colon ;-)


Segher

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-23 22:12     ` Thomas Koenig
@ 2020-11-24  4:28       ` Maciej W. Rozycki
  2020-11-24  5:27         ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-24  4:28 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: Toon Moene, gcc-patches, fortran

On Mon, 23 Nov 2020, Thomas Koenig wrote:

> >   Well it does not:
> > 
> > In file included from .../libgfortran/generated/maxval_r4.c:26:
> > .../libgfortran/generated/maxval_r4.c: In function 'maxval_r4':
> > .../libgfortran/libgfortran.h:292:30: warning: target format does not
> > support infinity
> >    292 | # define GFC_REAL_4_INFINITY __builtin_inff ()
> >        |                              ^~~~~~~~~~~~~~
> 
> This is guarded with
> 
> #ifdef __FLT_HAS_INFINITY__
> # define GFC_REAL_4_INFINITY __builtin_inff ()
> #endif
> 
> I don't know how or why __FLT_HAS_INFINITY is set for a target which
> does not support it, but if you get rid of that macro, that particular
> problem should be solved.

 Thanks for the hint; I didn't look into it any further not to distract 
myself from the scope of the project.  I have now, and the check you have 
quoted is obviously broken (as are all the remaining similar ones), given:

$ vax-netbsdelf-gcc -E -dM - < /dev/null | sort | grep _HAS_
#define __DBL_HAS_DENORM__ 0
#define __DBL_HAS_INFINITY__ 0
#define __DBL_HAS_QUIET_NAN__ 0
#define __FLT_HAS_DENORM__ 0
#define __FLT_HAS_INFINITY__ 0
#define __FLT_HAS_QUIET_NAN__ 0
#define __LDBL_HAS_DENORM__ 0
#define __LDBL_HAS_INFINITY__ 0
#define __LDBL_HAS_QUIET_NAN__ 0
$ 

which looks reasonable to me.  This seems straightforward to fix to me, so 
I'll include it along with verification I am about to schedule (assuming 
that this will be enough for libgfortran to actually build; obviously it 
hasn't been tried by anyone with such a setup for a while now, as these 
libgfortran checks date back to 2009).

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  4:28       ` Maciej W. Rozycki
@ 2020-11-24  5:27         ` Maciej W. Rozycki
  2020-11-24  6:04           ` Maciej W. Rozycki
  2020-11-25 22:26           ` coypu
  0 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-24  5:27 UTC (permalink / raw)
  To: Thomas Koenig
  Cc: Martin Husemann, Anders Magnusson, Toon Moene, gcc-patches, fortran

On Tue, 24 Nov 2020, Maciej W. Rozycki wrote:

> > I don't know how or why __FLT_HAS_INFINITY is set for a target which
> > does not support it, but if you get rid of that macro, that particular
> > problem should be solved.
> 
>  Thanks for the hint; I didn't look into it any further not to distract 
> myself from the scope of the project.  I have now, and the check you have 
> quoted is obviously broken (as are all the remaining similar ones), given:
> 
> $ vax-netbsdelf-gcc -E -dM - < /dev/null | sort | grep _HAS_
> #define __DBL_HAS_DENORM__ 0
> #define __DBL_HAS_INFINITY__ 0
> #define __DBL_HAS_QUIET_NAN__ 0
> #define __FLT_HAS_DENORM__ 0
> #define __FLT_HAS_INFINITY__ 0
> #define __FLT_HAS_QUIET_NAN__ 0
> #define __LDBL_HAS_DENORM__ 0
> #define __LDBL_HAS_INFINITY__ 0
> #define __LDBL_HAS_QUIET_NAN__ 0
> $ 
> 
> which looks reasonable to me.  This seems straightforward to fix to me, so 
> I'll include it along with verification I am about to schedule (assuming 
> that this will be enough for libgfortran to actually build; obviously it 
> hasn't been tried by anyone with such a setup for a while now, as these 
> libgfortran checks date back to 2009).

 Well, it is still broken, owing to NetBSD failing to implement POSIX 2008 
locale handling correctly, apparently deliberately[1], and missing 
uselocale(3)[2] while still providing newlocale(3).  This confuses our 
conditionals and consequently:

.../libgfortran/io/transfer.c: In function 'data_transfer_init_worker':
.../libgfortran/io/transfer.c:3416:30: error:
'old_locale_lock' undeclared (first use in this function)
 3416 |       __gthread_mutex_lock (&old_locale_lock);
      |                              ^~~~~~~~~~~~~~~

etc.

 We can probably work it around by downgrading to setlocale(3) for NetBSD 
(i.e. whenever either function is missing) unless someone from the NetBSD 
community contributes a better implementation (they seem to prefer their 
own non-standard printf_l(3) library API).

References:

[1] Martin Husemann, "Re: uselocale() function", 
    <https://mail-index.netbsd.org/netbsd-users/2017/02/14/msg019351.html>

[2] "The Open Group Base Specifications Issue 7, 2018 edition", IEEE Std 
    1003.1-2017 (Revision of IEEE Std 1003.1-2008),
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/uselocale.html>

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  5:27         ` Maciej W. Rozycki
@ 2020-11-24  6:04           ` Maciej W. Rozycki
  2020-11-24  6:16             ` Thomas Koenig
  2020-11-25 18:26             ` Maciej W. Rozycki
  2020-11-25 22:26           ` coypu
  1 sibling, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-24  6:04 UTC (permalink / raw)
  To: Thomas Koenig
  Cc: Martin Husemann, Anders Magnusson, Toon Moene, gcc-patches, fortran

On Tue, 24 Nov 2020, Maciej W. Rozycki wrote:

> > > I don't know how or why __FLT_HAS_INFINITY is set for a target which
> > > does not support it, but if you get rid of that macro, that particular
> > > problem should be solved.
> > 
> >  Thanks for the hint; I didn't look into it any further not to distract 
> > myself from the scope of the project.  I have now, and the check you have 
> > quoted is obviously broken (as are all the remaining similar ones), given:
> > 
> > $ vax-netbsdelf-gcc -E -dM - < /dev/null | sort | grep _HAS_
> > #define __DBL_HAS_DENORM__ 0
> > #define __DBL_HAS_INFINITY__ 0
> > #define __DBL_HAS_QUIET_NAN__ 0
> > #define __FLT_HAS_DENORM__ 0
> > #define __FLT_HAS_INFINITY__ 0
> > #define __FLT_HAS_QUIET_NAN__ 0
> > #define __LDBL_HAS_DENORM__ 0
> > #define __LDBL_HAS_INFINITY__ 0
> > #define __LDBL_HAS_QUIET_NAN__ 0
> > $ 
> > 
> > which looks reasonable to me.  This seems straightforward to fix to me, so 
> > I'll include it along with verification I am about to schedule (assuming 
> > that this will be enough for libgfortran to actually build; obviously it 
> > hasn't been tried by anyone with such a setup for a while now, as these 
> > libgfortran checks date back to 2009).
> 
>  Well, it is still broken, owing to NetBSD failing to implement POSIX 2008 
> locale handling correctly, apparently deliberately[1], and missing 
> uselocale(3)[2] while still providing newlocale(3).  This confuses our 
> conditionals and consequently:
> 
> .../libgfortran/io/transfer.c: In function 'data_transfer_init_worker':
> .../libgfortran/io/transfer.c:3416:30: error:
> 'old_locale_lock' undeclared (first use in this function)
>  3416 |       __gthread_mutex_lock (&old_locale_lock);
>       |                              ^~~~~~~~~~~~~~~
> 
> etc.
> 
>  We can probably work it around by downgrading to setlocale(3) for NetBSD 
> (i.e. whenever either function is missing) unless someone from the NetBSD 
> community contributes a better implementation (they seem to prefer their 
> own non-standard printf_l(3) library API).

 And now:

In file included from .../libgfortran/intrinsics/erfc_scaled.c:33:
.../libgfortran/intrinsics/erfc_scaled_inc.c:
In function 'erfc_scaled_r4':
.../libgfortran/intrinsics/erfc_scaled_inc.c:169:15: warning: target format does not support infinity
  169 |         res = __builtin_inf ();
      |               ^~~~~~~~~~~~~
In file included from .../libgfortran/intrinsics/erfc_scaled.c:39:
.../libgfortran/intrinsics/erfc_scaled_inc.c:
In function 'erfc_scaled_r8':
.../libgfortran/intrinsics/erfc_scaled_inc.c:82:15: warning: floating constant exceeds range of 'double'
   82 |               xbig = 26.543, xhuge = 6.71e+7, xmax = 2.53e+307;
      |               ^~~~
.../libgfortran/intrinsics/erfc_scaled_inc.c:169:15: warning: target format does not support infinity
  169 |         res = __builtin_inf ();
      |               ^~~~~~~~~~~~~

and:

.../libgfortran/intrinsics/c99_functions.c: In function 'tgamma':
.../libgfortran/intrinsics/c99_functions.c:1866:3: warning: floating constant truncated to zero [-Woverflow]
 1866 |   static const double xminin = 2.23e-308;
      |   ^~~~~~
.../libgfortran/intrinsics/c99_functions.c:1868:60: warning: target format does not support infinity
 1868 |   static const double xnan = __builtin_nan ("0x0"), xinf = __builtin_inf ();
      |                                                            ^~~~~~~~~~~~~{standard input}: Assembler messages:
{standard input}:487: Fatal error: Junk at end of expression "QNaN"
make[3]: *** [Makefile:6466: c99_functions.lo] Error 1

I am going to give up at this point, as porting libgfortran to non-IEEE FP 
is surely well beyond what I can afford to do right now.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  6:04           ` Maciej W. Rozycki
@ 2020-11-24  6:16             ` Thomas Koenig
  2020-11-25 19:22               ` Maciej W. Rozycki
  2020-11-25 18:26             ` Maciej W. Rozycki
  1 sibling, 1 reply; 117+ messages in thread
From: Thomas Koenig @ 2020-11-24  6:16 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Martin Husemann, Anders Magnusson, Toon Moene, gcc-patches, fortran

Am 24.11.20 um 07:04 schrieb Maciej W. Rozycki:
> I am going to give up at this point, as porting libgfortran to non-IEEE FP
> is surely well beyond what I can afford to do right now.

Can you file a PR about this? Eliminating __builtin_inf and friends
sounds doable.

And does anybody know what we should return in cases where the result
exceeds the maximum representable number?

Best regards

	Thomas

^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-20 15:30     ` Maciej W. Rozycki
@ 2020-11-24  6:19       ` Maciej W. Rozycki
  2020-11-24 11:03         ` Eric Botcazou
  2020-11-27 10:52         ` Ulrich Weigand
  0 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-24  6:19 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, Anders Magnusson

From: Matt Thomas <matt@3am-software.com>

Fix an ICE with the handling of RTL expressions like:

(subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67])
                    (const_int 4 [0x4]))
                (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59]))
            (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0)

that causes the compilation of libgomp to fail:

during RTL pass: reload
.../libgomp/ordered.c: In function 'GOMP_doacross_wait':
.../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
  507 | }
      | ^
0x10a3462b change_address_1
	.../gcc/emit-rtl.c:2275
0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
	.../gcc/emit-rtl.c:2409
0x10ae2993 alter_subreg(rtx_def**, bool)
	.../gcc/final.c:3368
0x10ae25cf cleanup_subreg_operands(rtx_insn*)
	.../gcc/final.c:3322
0x110922a3 reload(rtx_insn*, int)
	.../gcc/reload1.c:1232
0x10de2bf7 do_reload
	.../gcc/ira.c:5812
0x10de3377 execute
	.../gcc/ira.c:5986

in a `vax-netbsdelf' build, where an attempt is made to change the mode
of the contained memory reference to the mode of the containing SUBREG.
Such RTL expressions are produced by the VAX shift and rotate patterns
(`ashift', `ashiftrt', `rotate', `rotatert') where the count operand
always has the QI mode regardless of the mode, either SI or DI, of the
datum shifted or rotated.

Such a mode change cannot work where the memory reference uses the
indexed addressing mode, where a multiplier is implied that in the VAX
ISA depends on the width of the memory access requested and therefore
changing the machine mode would change the address calculation as well.

Avoid the attempt then by forcing the reload of any SUBREGs containing
a mode-dependent memory reference, also fixing these regressions:

FAIL: gcc.c-torture/compile/pr46883.c   -Os  (internal compiler error)
FAIL: gcc.c-torture/compile/pr46883.c   -Os  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
FAIL: gcc.dg/20050629-1.c (internal compiler error)
FAIL: gcc.dg/20050629-1.c (test for excess errors)
FAIL: c-c++-common/torture/pr53505.c   -Os  (internal compiler error)
FAIL: c-c++-common/torture/pr53505.c   -Os  (test for excess errors)
FAIL: gfortran.dg/coarray_failed_images_1.f08   -Os  (internal compiler error)
FAIL: gfortran.dg/coarray_stopped_images_1.f08   -Os  (internal compiler error)

With test case #0 included it causes a reload with:

(insn 15 14 16 4 (set (reg:SI 31)
        (ashift:SI (const_int 1 [0x1])
            (subreg:QI (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) 0))) "pr58901-0.c":15:12 94 {ashlsi3}
     (expr_list:REG_DEAD (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
        (nil)))

as follows:

Reloads for insn # 15
Reload 0: reload_in (SI) = (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
	ALL_REGS, RELOAD_FOR_INPUT (opnum = 2)
	reload_in_reg: (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
	reload_reg_rtx: (reg:SI 5 %r5)

resulting in:

(insn 37 14 15 4 (set (reg:SI 5 %r5)
        (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:25 i ] [25])
                        (const_int 4 [0x4]))
                    (reg/v/f:SI 4 %r4 [orig:29 s ] [29]))
                (const_int 4 [0x4])) [1 MEM[(int *)s_8(D) + 4B + _5 * 4]+0 S4 A32])) "pr58901-0.c":15:12 12 {movsi_2}
     (nil))
(insn 15 37 16 4 (set (reg:SI 2 %r2 [31])
        (ashift:SI (const_int 1 [0x1])
            (reg:QI 5 %r5))) "pr58901-0.c":15:12 94 {ashlsi3}
     (nil))

and assembly like:

.L3:
	movl 4(%r4)[%r1],%r5
	ashl %r5,$1,%r2
	xorl2 %r2,%r0
	incl %r1
	cmpl %r1,%r3
	jneq .L3

produced for the loop, providing optimization has been enabled.  

Likewise with test case #1 the reload of:

(insn 17 16 18 4 (set (reg:SI 34)
        (and:SI (subreg:SI (reg/v:DI 27 [ t ]) 4)
            (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
     (expr_list:REG_DEAD (reg/v:DI 27 [ t ])
        (nil)))

is as follows:

Reloads for insn # 17
Reload 0: reload_in (DI) = (reg/v:DI 27 [ t ])
	reload_out (SI) = (reg:SI 2 %r2 [34])
	ALL_REGS, RELOAD_OTHER (opnum = 0)
	reload_in_reg: (reg/v:DI 27 [ t ])
	reload_out_reg: (reg:SI 2 %r2 [34])
	reload_reg_rtx: (reg:DI 4 %r4)

resulting in:

(insn 40 16 17 4 (set (reg:DI 4 %r4)
        (mem/c:DI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:26 i ] [26])
                    (const_int 8 [0x8]))
                (reg/v/f:SI 3 %r3 [orig:30 s ] [30])) [1 MEM[(const struct s *)s_13(D) + _7 * 8]+0 S8 A32])) "pr58901-1.c":18:20 11 {movdi}
     (nil))
(insn 17 40 41 4 (set (reg:SI 4 %r4)
        (and:SI (reg:SI 5 %r5 [+4 ])
            (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
     (nil))

and assembly like:

.L3:
	movq (%r3)[%r1],%r4
	bicl3 $-2,%r5,%r4
	addl2 %r4,%r0
	jaoblss %r0,%r1,.L3

First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.

2020-11-24  Matt Thomas  <matt@3am-software.com>
	    Maciej W. Rozycki  <macro@linux-mips.org>

	gcc/
	PR target/58901
	* reload.c (push_reload): Also reload the inner expression of a 
	SUBREG for pseudos associated with a mode-dependent memory 
	reference.
	(find_reloads): Force a reload likewise.

2020-11-24  Maciej W. Rozycki  <macro@linux-mips.org>

	gcc/testsuite/
	PR target/58901
	* gcc.c-torture/compile/pr58901-0.c: New test.
	* gcc.c-torture/compile/pr58901-1.c: New test.
---
Hi Eric,

On Fri, 20 Nov 2020, Maciej W. Rozycki wrote:

> > The handling of this family of reloads is supposed to be done by the block of 
> > code just above though, i.e. at line 1023.  Can't we add the test based on 
> > mode_dependent_address_p to this block, e.g. after:
> > 
> > 	  || (REG_P (SUBREG_REG (in))
> > 	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
> > 	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
> > 					 GET_MODE (SUBREG_REG 
> > (in)), inmode))))
> > 
> > instead?
> 
>  Thank you for your input, I'll have a look.  Coming from Matt this is the 
> only change of the series I have just merged without looking into it too 
> much, so as not to spend too much time with side issues (there were too 
> many already).

 You were right about the correct placement of the check, but it was a 
part of the solution only.

 I looked into why it did not work on its own and (mind that I have not 
worked with this part of GCC before) I have realised something was not 
right about it.  The thing was the reload was only requested as optional 
(and later discarded) under the premise of being an optimisation only 
(i.e. called from reload.c:4125 in `find_reloads'), while indeed it is 
required whether optimising or not, even though the VAX backend does not 
appear to produce mode-dependent addresses in the latter case, or at least 
I haven't seen it doing so.

 So I have investigated what needs to be done for the reload to become 
unconditional and come up with this update.  Note that we need to handle a 
mode change whether it is for the low part of the inner reference or not.  
The latter case is what turned out to actually trigger with pr53505.c, 
which this update actually produces better code for, removing a useless 
move (and frame slot creation for a static register):

@@ -5,7 +5,7 @@
 .globl foo
 	.type	foo, @function
 foo:
-	.word 0x40
+	.word 0
 	subl2 $4,%sp
 	movl 4(%ap),%r2
 	clrl %r0
@@ -18,7 +18,6 @@
 	calls $0,abort
 .L3:
 	movq (%r2)[%r0],%r4
-	movl %r5,%r6
 	rotl $16,%r5,%r3
 	bicl2 $-2,%r3
 	addl2 %r3,%r1

which was of course the result of an unnecessary reload of the outer 
expression the original change did.

 I have reduced the libgomp build failure and pr53505.c to test cases #0 
and #1 included respectively (where #1 actually triggers across all 
optimisation levels rather than just `-Os', though with 05/31 this goes 
back to `-Os' only); while the failure is VAX-specific code involved is 
not, so I think there'll be no harm with including them in the generic 
part of our testsuite for good measure.

 I think it is interesting to note that with #0 for some reason for the 
failure to trigger the struct has to be passed by reference rather than 
value and for #1 there has to be the intermediate struct assignment in the 
loop; otherwise the indexed addressing mode won't trigger and the base 
register will instead be incremented by four.

 Also I wonder why with #0 the middle end tries to be too smart and makes 
the loop's continuation condition `ne' rather `gt' as with #1, causing the 
resulting RTL not to match the pattern for `jaoblss' and consequently more 
elaborate code to be produced, even though in both cases the control 
statement uses the `<' relational operator.  Anyway, that's unrelated.

>  It'll take me a couple of days to push the new version through regression 
> testing, and I'll post it once that is complete along with any other 
> updates someone may request.

 I actually missed the high-part case with my first attempt and thankfully 
pr53505.c has caught it.  It means however that I've had to rerun testing, 
and given I have literally only just started it now I expect results Thu 
morning only.

 NB I find the reindentation resulting in `push_reload' awful, just as I 
do either version of the massive logical expression involved.  Perhaps we 
could factor these out into `static inline' functions sometime, and then 
have them split into individual returns within?

  Maciej
---
 gcc/reload.c                                    |  105 +++++++++++++++---------
 gcc/testsuite/gcc.c-torture/compile/pr58901-0.c |   17 +++
 gcc/testsuite/gcc.c-torture/compile/pr58901-1.c |   21 ++++
 3 files changed, 107 insertions(+), 36 deletions(-)

Index: gcc/gcc/reload.c
===================================================================
--- gcc.orig/gcc/reload.c
+++ gcc/gcc/reload.c
@@ -1043,53 +1043,73 @@ push_reload (rtx in, rtx out, rtx *inloc
      Also reload the inner expression if it does not require a secondary
      reload but the SUBREG does.
 
-     Finally, reload the inner expression if it is a register that is in
+     Also reload the inner expression if it is a register that is in
      the class whose registers cannot be referenced in a different size
      and M1 is not the same size as M2.  If subreg_lowpart_p is false, we
      cannot reload just the inside since we might end up with the wrong
      register class.  But if it is inside a STRICT_LOW_PART, we have
-     no choice, so we hope we do get the right register class there.  */
+     no choice, so we hope we do get the right register class there.
+
+     Finally, reload the inner expression if it is a pseudo that will
+     become a MEM and the MEM has a mode-dependent address, as in that
+     case we obviously cannot change the mode of the MEM to that of the
+     containing SUBREG as that would change the interpretation of the
+     address.  */
 
   scalar_int_mode inner_mode;
   if (in != 0 && GET_CODE (in) == SUBREG
-      && (subreg_lowpart_p (in) || strict_low)
       && targetm.can_change_mode_class (GET_MODE (SUBREG_REG (in)),
 					inmode, rclass)
       && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (in))]
-      && (CONSTANT_P (SUBREG_REG (in))
-	  || GET_CODE (SUBREG_REG (in)) == PLUS
-	  || strict_low
-	  || (((REG_P (SUBREG_REG (in))
-		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
-	       || MEM_P (SUBREG_REG (in)))
-	      && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-		  || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
-		      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)),
-						 &inner_mode)
-		      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
-		      && paradoxical_subreg_p (inmode, inner_mode)
-		      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
-		  || (WORD_REGISTER_OPERATIONS
-		      && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-		      && (known_equal_after_align_down
-			  (GET_MODE_SIZE (inmode) - 1,
-			   GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1,
-			   UNITS_PER_WORD)))))
-	  || (REG_P (SUBREG_REG (in))
-	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-	      /* The case where out is nonzero
-		 is handled differently in the following statement.  */
-	      && (out == 0 || subreg_lowpart_p (in))
-	      && (complex_word_subreg_p (inmode, SUBREG_REG (in))
-		  || !targetm.hard_regno_mode_ok (subreg_regno (in), inmode)))
-	  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
-	      && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
-					  SUBREG_REG (in))
-		  == NO_REGS))
+      && (strict_low
+	  || (subreg_lowpart_p (in)
+	      && (CONSTANT_P (SUBREG_REG (in))
+		  || GET_CODE (SUBREG_REG (in)) == PLUS
+		  || strict_low
+		  || (((REG_P (SUBREG_REG (in))
+			&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
+		       || MEM_P (SUBREG_REG (in)))
+		      && (paradoxical_subreg_p (inmode,
+						GET_MODE (SUBREG_REG (in)))
+			  || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
+			      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG
+								   (in)),
+							 &inner_mode)
+			      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
+			      && paradoxical_subreg_p (inmode, inner_mode)
+			      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
+			  || (WORD_REGISTER_OPERATIONS
+			      && partial_subreg_p (inmode,
+						   GET_MODE (SUBREG_REG (in)))
+			      && (known_equal_after_align_down
+				  (GET_MODE_SIZE (inmode) - 1,
+				   GET_MODE_SIZE (GET_MODE (SUBREG_REG
+							    (in))) - 1,
+				   UNITS_PER_WORD)))))
+		  || (REG_P (SUBREG_REG (in))
+		      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
+		      /* The case where out is nonzero
+			 is handled differently in the following statement.  */
+		      && (out == 0 || subreg_lowpart_p (in))
+		      && (complex_word_subreg_p (inmode, SUBREG_REG (in))
+			  || !targetm.hard_regno_mode_ok (subreg_regno (in),
+							  inmode)))
+		  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
+		      && (secondary_reload_class (1, rclass,
+						  GET_MODE (SUBREG_REG (in)),
+						  SUBREG_REG (in))
+			  == NO_REGS))
+		  || (REG_P (SUBREG_REG (in))
+		      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
+		      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
+						 GET_MODE (SUBREG_REG (in)),
+						 inmode))))
 	  || (REG_P (SUBREG_REG (in))
-	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
-					 GET_MODE (SUBREG_REG (in)), inmode))))
+	      && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER
+	      && reg_equiv_mem (REGNO (SUBREG_REG (in)))
+	      && (mode_dependent_address_p
+		  (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in))), 0),
+		   MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in)))))))))
     {
 #ifdef LIMIT_RELOAD_CLASS
       in_subreg_loc = inloc;
@@ -3157,6 +3177,19 @@ find_reloads (rtx_insn *insn, int replac
 				  && paradoxical_subreg_p (operand_mode[i],
 							   inner_mode)
 				  && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)))
+		      /* We must force a reload of a SUBREG's inner expression
+			 if it is a pseudo that will become a MEM and the MEM
+			 has a mode-dependent address, as in that case we
+			 obviously cannot change the mode of the MEM to that
+			 of the containing SUBREG as that would change the
+			 interpretation of the address.  */
+		      || (REG_P (operand)
+			  && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+			  && reg_equiv_mem (REGNO (operand))
+			  && (mode_dependent_address_p
+			      (XEXP (reg_equiv_mem (REGNO (operand)), 0),
+			       (MEM_ADDR_SPACE
+				(reg_equiv_mem (REGNO (operand)))))))
 		      )
 		    force_reload = 1;
 		}
Index: gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c
@@ -0,0 +1,17 @@
+typedef signed int __attribute__ ((mode (SI))) int_t;
+
+struct s
+{
+  int_t n;
+  int_t c[];
+};
+
+int_t
+ashlsi (int_t x, const struct s *s)
+{
+  int_t i;
+
+  for (i = 0; i < s->n; i++)
+    x ^= 1 << s->c[i];
+  return x;
+}
Index: gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c
@@ -0,0 +1,21 @@
+typedef int __attribute__ ((mode (SI))) int_t;
+
+struct s
+{
+  int_t n;
+  int_t m : 1;
+  int_t l : 31;
+};
+
+int_t
+movdi (int_t x, const struct s *s)
+{
+  int_t i;
+
+  for (i = 0; i < x; i++)
+    {
+      const struct s t = s[i];
+      x += t.m ? 1 : 0;
+    }
+  return x;
+}

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-24  6:19       ` [PATCH v2 " Maciej W. Rozycki
@ 2020-11-24 11:03         ` Eric Botcazou
  2020-11-26 17:22           ` Maciej W. Rozycki
  2020-11-27 10:52         ` Ulrich Weigand
  1 sibling, 1 reply; 117+ messages in thread
From: Eric Botcazou @ 2020-11-24 11:03 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson

> First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.
> 
> 2020-11-24  Matt Thomas  <matt@3am-software.com>
> 	    Maciej W. Rozycki  <macro@linux-mips.org>
> 
> 	gcc/
> 	PR target/58901
> 	* reload.c (push_reload): Also reload the inner expression of a
> 	SUBREG for pseudos associated with a mode-dependent memory
> 	reference.
> 	(find_reloads): Force a reload likewise.

Thanks for pursuing this.  Although the duplication is unfortunate, I think 
that this version is more in line with the existing processing so I would go 
for it.  You probably need a formal ack from Ulrich(?) or Jeff though.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-23 15:48 ` Paul Koning
@ 2020-11-25 17:07   ` Maciej W. Rozycki
  2020-11-28 18:48     ` Paul Koning
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-25 17:07 UTC (permalink / raw)
  To: Paul Koning; +Cc: GCC Patches, Jeff Law

On Mon, 23 Nov 2020, Paul Koning wrote:

> > Then there is a fix for the PDP11 backend addressing an issue I found in 
> > the handling of floating-point comparisons.  Unlike all the other changes 
> > this one has not been regression-tested, not even built as I have no idea 
> > how to prepare a development environment for a PDP11 target (also none of 
> > my VAX pieces is old enough to support PDP11 machine code execution).
> 
> I agree this is a correct change, interesting that it was missed before.  
> You'd expect some ICE issues from that mistake.  Perhaps there were and 
> I didn't realize the cause; the PDP11 test run is not yet fully clean.

 Nothing like that, I wouldn't expect an ICE here.  Just as none happened 
with the VAX backend before a test case made me realise a corresponding 
change was required.  It's just a pessimisation: the RTL simply doesn't 
match and the comparison to remove stays.

> I've hacked together a primitive newlib based "bare metal" execution 
> test setup that uses SIMH, but it's not a particularly clean setup.  
> And it hasn't been posted, I hope to be able to do that at some point.

 Hmm, I gather those systems are able to run some kind of BSD Unix: don't 
they support the r-commands which would allow you to run DejaGNU testing 
with a realistic environment PDP-11 hardware would be usually used with, 
possibly on actual hardware even?  I always feel a bit uneasy about the 
accuracy of any simulation (having suffered from bugs in QEMU causing 
false negatives in software verification).

 While I would expect old BSD libc to miss some of the C language features 
considered standard nowadays, I think at least the C GCC frontend runtime 
(libgcc.a) and the test suite do not overall rely on their presence, and 
any individual test cases that do can be easily excluded.

> Thanks for the fix.

 I take it as an approval and will apply the change then along with the 
rest of the series.  Thank you for your review.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  6:04           ` Maciej W. Rozycki
  2020-11-24  6:16             ` Thomas Koenig
@ 2020-11-25 18:26             ` Maciej W. Rozycki
  2020-11-25 22:20               ` Joseph Myers
  1 sibling, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-25 18:26 UTC (permalink / raw)
  To: Thomas Koenig
  Cc: Martin Husemann, Anders Magnusson, Toon Moene, gcc-patches, fortran

On Tue, 24 Nov 2020, Maciej W. Rozycki wrote:

> I am going to give up at this point, as porting libgfortran to non-IEEE FP 
> is surely well beyond what I can afford to do right now.

 I have now posted fixes for the issues handled so far.

 For the other pieces that are missing perhaps my work I did many years 
ago to port glibc 2.4 (the last one I was able to cook up without NPTL), 
and specifically libm within, to the never-upstreamed VAX/Linux target 
might be useful to complete the effort, as there seems to be an overlap 
here.  That port hasn't been fully verified though and I do not promise 
doing any work related to it anytime either.  The glibc patches continue 
being available online to download and use under the terms of the GNU GPL 
for anyone though.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
                   ` (33 preceding siblings ...)
  2020-11-23 15:48 ` Paul Koning
@ 2020-11-25 18:36 ` Maciej W. Rozycki
  2020-11-26 14:46   ` Ian Lance Taylor
  2020-11-29 17:56   ` Martin Sebor
  34 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-25 18:36 UTC (permalink / raw)
  To: Ian Lance Taylor, gcc-patches
  Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

On Fri, 20 Nov 2020, Maciej W. Rozycki wrote:

>  These changes have been regression-tested throughout development with the 
> `vax-netbsdelf' target running NetBSD 9.0, using said VAXstation 4000/60, 
> which uses the Mariah implemementation of the VAX architecture.  The host 
> used was `powerpc64le-linux-gnu' and occasionally `x86_64-linux-gnu' as 
> well; changes outside the VAX backend were all natively bootstrapped and 
> regression-tested with both these hosts.

 I forgot to note that I have been going through this final verification 
with the native compiler and the `vax-netbsdelf' cross-compiler built with 
it both configured with `--disable-werror'.  This is due to a recent 
regression with the Go frontend causing a build error otherwise:

.../gcc/go/gofrontend/go-diagnostics.cc: In function 'std::string expand_message(const char*, va_list)':
.../gcc/go/gofrontend/go-diagnostics.cc:110:61: error: '<anonymous>' may be used uninitialized [-Werror=maybe-uninitialized]
  110 |                      "memory allocation failed in vasprintf");
      |                                                             ^
In file included from .../prev-powerpc64le-linux-gnu/libstdc++-v3/include/string:55,
                 from .../gcc/go/go-system.h:34,
                 from .../gcc/go/gofrontend/go-linemap.h:10,
                 from .../gcc/go/gofrontend/go-diagnostics.h:10,
                 from .../gcc/go/gofrontend/go-diagnostics.cc:7:
.../prev-powerpc64le-linux-gnu/libstdc++-v3/include/bits/basic_string.h:525:7: note: by argument 3 of type 'const std::allocator<char>&' to 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with <template-parameter-2-1> = std::allocator<char>; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' declared here
  525 |       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
      |       ^~~~~~~~~~~~
.../gcc/go/gofrontend/go-diagnostics.cc:110:61: note: '<anonymous>' declared here
  110 |                      "memory allocation failed in vasprintf");
      |                                                             ^
cc1plus: all warnings being treated as errors
make[3]: *** [.../gcc/go/Make-lang.in:242: go/go-diagnostics.o] Error 1

the cause for which I decided I could not afford the time to track down.  
Perhaps it has been fixed since, but mentioning it in case it has not.

 Earlier verification iterations were done with `--enable-werror-always'.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  6:16             ` Thomas Koenig
@ 2020-11-25 19:22               ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-25 19:22 UTC (permalink / raw)
  To: Thomas Koenig
  Cc: Martin Husemann, Anders Magnusson, Toon Moene, gcc-patches, fortran

On Tue, 24 Nov 2020, Thomas Koenig wrote:

> > I am going to give up at this point, as porting libgfortran to non-IEEE FP
> > is surely well beyond what I can afford to do right now.
> 
> Can you file a PR about this? Eliminating __builtin_inf and friends
> sounds doable.

 There's more to that unfortunately.  I would have done it right away if 
it was so easy.

> And does anybody know what we should return in cases where the result
> exceeds the maximum representable number?

 Presumably the standard has it (implementation-specific for non-IEEE-754 
I suppose; in the VAX FP ISA an underflow optionally traps, and otherwise 
produces a zero result, while an overflow traps unconditionally and keeps 
the destination operand unchanged).

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 18:26             ` Maciej W. Rozycki
@ 2020-11-25 22:20               ` Joseph Myers
  2020-11-26 18:01                 ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Joseph Myers @ 2020-11-25 22:20 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Thomas Koenig, Anders Magnusson, Martin Husemann, gcc-patches, fortran

On Wed, 25 Nov 2020, Maciej W. Rozycki wrote:

>  For the other pieces that are missing perhaps my work I did many years 
> ago to port glibc 2.4 (the last one I was able to cook up without NPTL), 
> and specifically libm within, to the never-upstreamed VAX/Linux target 
> might be useful to complete the effort, as there seems to be an overlap 
> here.  That port hasn't been fully verified though and I do not promise 
> doing any work related to it anytime either.  The glibc patches continue 
> being available online to download and use under the terms of the GNU GPL 
> for anyone though.

I think I mentioned before: if you wish to bring a VAX port back to 
current glibc, I think it would make more sense to use software IEEE 
floating point rather than adding new support to glibc for a non-IEEE 
floating-point format.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-24  5:27         ` Maciej W. Rozycki
  2020-11-24  6:04           ` Maciej W. Rozycki
@ 2020-11-25 22:26           ` coypu
  2020-11-26 17:59             ` Maciej W. Rozycki
  1 sibling, 1 reply; 117+ messages in thread
From: coypu @ 2020-11-25 22:26 UTC (permalink / raw)
  To: gcc-patches

On Tue, Nov 24, 2020 at 05:27:10AM +0000, Maciej W. Rozycki wrote:
> On Tue, 24 Nov 2020, Maciej W. Rozycki wrote:
> 
> > > I don't know how or why __FLT_HAS_INFINITY is set for a target which
> > > does not support it, but if you get rid of that macro, that particular
> > > problem should be solved.
> > 
> >  Thanks for the hint; I didn't look into it any further not to distract 
> > myself from the scope of the project.  I have now, and the check you have 
> > quoted is obviously broken (as are all the remaining similar ones), given:
> > 
> > $ vax-netbsdelf-gcc -E -dM - < /dev/null | sort | grep _HAS_
> > #define __DBL_HAS_DENORM__ 0
> > #define __DBL_HAS_INFINITY__ 0
> > #define __DBL_HAS_QUIET_NAN__ 0
> > #define __FLT_HAS_DENORM__ 0
> > #define __FLT_HAS_INFINITY__ 0
> > #define __FLT_HAS_QUIET_NAN__ 0
> > #define __LDBL_HAS_DENORM__ 0
> > #define __LDBL_HAS_INFINITY__ 0
> > #define __LDBL_HAS_QUIET_NAN__ 0
> > $ 
> > 
> > which looks reasonable to me.  This seems straightforward to fix to me, so 
> > I'll include it along with verification I am about to schedule (assuming 
> > that this will be enough for libgfortran to actually build; obviously it 
> > hasn't been tried by anyone with such a setup for a while now, as these 
> > libgfortran checks date back to 2009).
> 
>  Well, it is still broken, owing to NetBSD failing to implement POSIX 2008 
> locale handling correctly, apparently deliberately[1], and missing 
> uselocale(3)[2] while still providing newlocale(3).  This confuses our 
> conditionals and consequently:
> 
> .../libgfortran/io/transfer.c: In function 'data_transfer_init_worker':
> .../libgfortran/io/transfer.c:3416:30: error:
> 'old_locale_lock' undeclared (first use in this function)
>  3416 |       __gthread_mutex_lock (&old_locale_lock);
>       |                              ^~~~~~~~~~~~~~~
> 
> etc.
> 
>  We can probably work it around by downgrading to setlocale(3) for NetBSD 
> (i.e. whenever either function is missing) unless someone from the NetBSD 
> community contributes a better implementation (they seem to prefer their 
> own non-standard printf_l(3) library API).

Hi Maciej,

I've been building successfully with setting:
export ac_cv_func_freelocale=no
export ac_cv_func_newlocale=no
export ac_cv_func_uselocale=no

I think the code to avoid these functions already exists, but just the
configure tests need tuning.

Also, this is amazing work!

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 18:36 ` Maciej W. Rozycki
@ 2020-11-26 14:46   ` Ian Lance Taylor
  2020-11-26 18:07     ` Maciej W. Rozycki
  2020-11-29 17:56   ` Martin Sebor
  1 sibling, 1 reply; 117+ messages in thread
From: Ian Lance Taylor @ 2020-11-26 14:46 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson

On Wed, Nov 25, 2020 at 10:36 AM Maciej W. Rozycki <macro@linux-mips.org> wrote:
>
> On Fri, 20 Nov 2020, Maciej W. Rozycki wrote:
>
> >  These changes have been regression-tested throughout development with the
> > `vax-netbsdelf' target running NetBSD 9.0, using said VAXstation 4000/60,
> > which uses the Mariah implemementation of the VAX architecture.  The host
> > used was `powerpc64le-linux-gnu' and occasionally `x86_64-linux-gnu' as
> > well; changes outside the VAX backend were all natively bootstrapped and
> > regression-tested with both these hosts.
>
>  I forgot to note that I have been going through this final verification
> with the native compiler and the `vax-netbsdelf' cross-compiler built with
> it both configured with `--disable-werror'.  This is due to a recent
> regression with the Go frontend causing a build error otherwise:
>
> .../gcc/go/gofrontend/go-diagnostics.cc: In function 'std::string expand_message(const char*, va_list)':
> .../gcc/go/gofrontend/go-diagnostics.cc:110:61: error: '<anonymous>' may be used uninitialized [-Werror=maybe-uninitialized]
>   110 |                      "memory allocation failed in vasprintf");
>       |                                                             ^
> In file included from .../prev-powerpc64le-linux-gnu/libstdc++-v3/include/string:55,
>                  from .../gcc/go/go-system.h:34,
>                  from .../gcc/go/gofrontend/go-linemap.h:10,
>                  from .../gcc/go/gofrontend/go-diagnostics.h:10,
>                  from .../gcc/go/gofrontend/go-diagnostics.cc:7:
> .../prev-powerpc64le-linux-gnu/libstdc++-v3/include/bits/basic_string.h:525:7: note: by argument 3 of type 'const std::allocator<char>&' to 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with <template-parameter-2-1> = std::allocator<char>; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' declared here
>   525 |       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
>       |       ^~~~~~~~~~~~
> .../gcc/go/gofrontend/go-diagnostics.cc:110:61: note: '<anonymous>' declared here
>   110 |                      "memory allocation failed in vasprintf");
>       |                                                             ^
> cc1plus: all warnings being treated as errors
> make[3]: *** [.../gcc/go/Make-lang.in:242: go/go-diagnostics.o] Error 1
>
> the cause for which I decided I could not afford the time to track down.
> Perhaps it has been fixed since, but mentioning it in case it has not.
>
>  Earlier verification iterations were done with `--enable-werror-always'.

I just want to note that as far as I can tell this is not a bug in the
Go frontend code.

Ian

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-24 11:03         ` Eric Botcazou
@ 2020-11-26 17:22           ` Maciej W. Rozycki
  2020-11-27  3:51             ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-26 17:22 UTC (permalink / raw)
  To: Eric Botcazou, Ulrich Weigand, Jeff Law; +Cc: gcc-patches, Anders Magnusson

On Tue, 24 Nov 2020, Eric Botcazou wrote:

> > First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.
> > 
> > 2020-11-24  Matt Thomas  <matt@3am-software.com>
> > 	    Maciej W. Rozycki  <macro@linux-mips.org>
> > 
> > 	gcc/
> > 	PR target/58901
> > 	* reload.c (push_reload): Also reload the inner expression of a
> > 	SUBREG for pseudos associated with a mode-dependent memory
> > 	reference.
> > 	(find_reloads): Force a reload likewise.
> 
> Thanks for pursuing this.  Although the duplication is unfortunate, I think 
> that this version is more in line with the existing processing so I would go 
> for it.  You probably need a formal ack from Ulrich(?) or Jeff though.

 This has completed verification now with good results.

 OK to apply then?  That would let the whole series through once it's gone 
through final verification (now ongoing; ETC: Mon, Nov 30th).

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 22:26           ` coypu
@ 2020-11-26 17:59             ` Maciej W. Rozycki
  2020-11-26 19:35               ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-26 17:59 UTC (permalink / raw)
  To: coypu; +Cc: gcc-patches

On Wed, 25 Nov 2020, coypu@sdf.org wrote:

> I've been building successfully with setting:
> export ac_cv_func_freelocale=no
> export ac_cv_func_newlocale=no
> export ac_cv_func_uselocale=no

 It's a workaround really, though surely one that works; I've done things 
like this myself regularly, especially for cross-compilation where the 
right setting cannot be determined by `configure' and the default is 
either wrong or bails out (it used to be the case with type sizes, very 
painful, until a clever trick was invented with one version of autoconf).

 Overall a plain `/path/to/configure' invocation is expected to do the 
right thing though for whatever the default configuration of a software 
piece is.

 Also by "building successfully" do you mean someone has actually ported 
libgfortran locally for VAX FP support, or is it just with NetBSD ports 
that use IEEE-754 FP?

> I think the code to avoid these functions already exists, but just the
> configure tests need tuning.

 I chose to update actual code instead as I found it more straightforward. 
Fix committed now; commit beb9afcaf146 ("libgfortran: Verify the presence 
of all functions for POSIX 2008 locale").

> Also, this is amazing work!

 Thanks, appreciated, although I've been doing this kind of things for 
some 20 years now (and much longer when it comes to all kinds of computer 
programming and fiddling with microprocessors), so it's bread and butter 
to me really.  I'd have had to switch fields by now if I used not to get 
such stuff right.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 22:20               ` Joseph Myers
@ 2020-11-26 18:01                 ` Maciej W. Rozycki
  2020-11-26 18:08                   ` Martin Husemann
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-26 18:01 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Thomas Koenig, Anders Magnusson, Martin Husemann, gcc-patches, fortran

On Wed, 25 Nov 2020, Joseph Myers wrote:

> >  For the other pieces that are missing perhaps my work I did many years 
> > ago to port glibc 2.4 (the last one I was able to cook up without NPTL), 
> > and specifically libm within, to the never-upstreamed VAX/Linux target 
> > might be useful to complete the effort, as there seems to be an overlap 
> > here.  That port hasn't been fully verified though and I do not promise 
> > doing any work related to it anytime either.  The glibc patches continue 
> > being available online to download and use under the terms of the GNU GPL 
> > for anyone though.
> 
> I think I mentioned before: if you wish to bring a VAX port back to 
> current glibc, I think it would make more sense to use software IEEE 
> floating point rather than adding new support to glibc for a non-IEEE 
> floating-point format.

 Right, that would be the path of least resistance (non-FP VAX bits are 
obviously limited and boil down to the OS interface and some handwritten 
assembly such as for optimised string ops), and surely the least involving 
one maintenance-wise, so perhaps the only acceptable compromise these days 
given that VAX is a niche of a niche now.

 The kernel part would have to happen first though, and the old effort 
became stuck in 2.6 days, so clearly not suitable for upstreaming.  Back 
in the day I did enough kernel updates to get interrupt handling right, 
i.e. the IPL stuff, based on what the Alpha port does, which is really the 
same, and then on top of it ptrace(2) support along with a native GDB and 
a `gdbserver' port so that I could actually debug the outstanding userland 
issues.

 But that was surely not enough even back then and is even less so now.  
FWIW I was able to run single-user `bash' (with `ncurses', etc.) and some 
other programs; native GCC crashed as did GDB, due to a bug leading to 
stack exhaustion, but `gdbserver' worked along with single-stepping, etc., 
so that was a good starting point.

 The VAX/NetBSD port however does use hardware FP in their libm as far as 
I can tell, so I guess it would be reasonable for libgfortran to do so as 
well.  I haven't checked how correct their implementation actually is, but 
barring evidence otherwise I would assume they did the right thing.  

 Without all the NaN/denormal stuff the handling should be much simpler I 
believe, though I gather some numeric algorithms do rely on the presence 
of denormals to produce reasonable results in some boundary cases.  These 
would be lost or a different algorithm would have to be chosen for the 
respective computations I suppose.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-26 14:46   ` Ian Lance Taylor
@ 2020-11-26 18:07     ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-26 18:07 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, Anders Magnusson

On Thu, 26 Nov 2020, Ian Lance Taylor wrote:

> I just want to note that as far as I can tell this is not a bug in the
> Go frontend code.

 Ack.  I thought it might be the case as the file in question hasn't 
changed for a while now, so it wasn't a Go frontend change that triggered 
the warning.  Just a heads-up anyway.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-26 18:01                 ` Maciej W. Rozycki
@ 2020-11-26 18:08                   ` Martin Husemann
  2020-12-08 14:38                     ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Martin Husemann @ 2020-11-26 18:08 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Joseph Myers, Thomas Koenig, Anders Magnusson, gcc-patches, fortran

On Thu, Nov 26, 2020 at 06:01:31PM +0000, Maciej W. Rozycki wrote:
>  The VAX/NetBSD port however does use hardware FP in their libm as far as 
> I can tell, so I guess it would be reasonable for libgfortran to do so as 
> well.  I haven't checked how correct their implementation actually is, but 
> barring evidence otherwise I would assume they did the right thing.  

It does, but it is not totally correct in all places (due to gcc issues
some parts have not received good testing, and others clearly are broken,
eg. when tables are used that have not been adjusted for the different
limits in VAX float/double formats).

Should be a lot easier to fix with newer gcc soonish (I hope).

Martin

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-26 17:59             ` Maciej W. Rozycki
@ 2020-11-26 19:35               ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-26 19:35 UTC (permalink / raw)
  To: coypu; +Cc: gcc-patches

On Thu, 26 Nov 2020, Maciej W. Rozycki wrote:

> > Also, this is amazing work!
> 
>  Thanks, appreciated, although I've been doing this kind of things for 
> some 20 years now (and much longer when it comes to all kinds of computer 
> programming and fiddling with microprocessors), so it's bread and butter 
> to me really.  I'd have had to switch fields by now if I used not to get 
> such stuff right.

 On second thoughts I realised this may have sounded a bit harsh even 
though meant to be a joke really.  Apologies for that.  I feel really 
happy all the conditions clicked and I was in the right place and time to 
save the VAX port from obsoletion.  And thank you for your appreciation!

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-26 17:22           ` Maciej W. Rozycki
@ 2020-11-27  3:51             ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-27  3:51 UTC (permalink / raw)
  To: Eric Botcazou, Ulrich Weigand, Jeff Law; +Cc: gcc-patches, Anders Magnusson

On Thu, 26 Nov 2020, Maciej W. Rozycki wrote:

> > > 	PR target/58901
> > > 	* reload.c (push_reload): Also reload the inner expression of a
> > > 	SUBREG for pseudos associated with a mode-dependent memory
> > > 	reference.
> > > 	(find_reloads): Force a reload likewise.
> > 
> > Thanks for pursuing this.  Although the duplication is unfortunate, I think 
> > that this version is more in line with the existing processing so I would go 
> > for it.  You probably need a formal ack from Ulrich(?) or Jeff though.
> 
>  This has completed verification now with good results.
> 
>  OK to apply then?  That would let the whole series through once it's gone 
> through final verification (now ongoing; ETC: Mon, Nov 30th).

 FAOD verification included bootstraps with native `powerpc64le-linux-gnu' 
and `x86_64-linux-gnu' systems, a cross-build of a `vax-netbsdelf' target 
compiler with a `powerpc64le-linux-gnu' build/host system, and then full 
regression-testing of all the components built across the three setups.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-24  6:19       ` [PATCH v2 " Maciej W. Rozycki
  2020-11-24 11:03         ` Eric Botcazou
@ 2020-11-27 10:52         ` Ulrich Weigand
  2020-11-27 19:22           ` Maciej W. Rozycki
  1 sibling, 1 reply; 117+ messages in thread
From: Ulrich Weigand @ 2020-11-27 10:52 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Eric Botcazou, Jeff Law, Anders Magnusson

On Tue, Nov 24, 2020 at 06:19:41AM +0000, Maciej W. Rozycki wrote: 

>  NB I find the reindentation resulting in `push_reload' awful, just as I 
> do either version of the massive logical expression involved.  Perhaps we 
> could factor these out into `static inline' functions sometime, and then 
> have them split into individual returns within?

I'm generally hesitant to do a lot of changes to the reload code base
at this stage.  The strategy rather is to move all remaining targets
over to LRA and then simply delete reload :-)

Given that you're modernizing the vax target, I'm wondering if you
shouldn't rather go all the way and move it over to LRA as well,
then you wouldn't be affected by any remaining reload deficiencies.
(The major hurdle so far was that LRA doesn't support CC0, but it
looks like you're removing that anyway ...)

> +      && (strict_low
> +	  || (subreg_lowpart_p (in)
> +	      && (CONSTANT_P (SUBREG_REG (in))
> +		  || GET_CODE (SUBREG_REG (in)) == PLUS
> +		  || strict_low

If we do this, then that "|| strict_low" clause is now redundant. 

> +	      && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER
> +	      && reg_equiv_mem (REGNO (SUBREG_REG (in)))
> +	      && (mode_dependent_address_p
> +		  (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in))), 0),
> +		   MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in)))))))))

I guess this is not incorrect, but I'm wondering if it would be
*complete* -- there are other cases where reload replaces a pseudo
with a MEM even where reg_equiv_mem is null.

That said, if it fixes the test suite errors you're seeing, it would
probably be OK to go with just this minimal change -- unless we can
just move to LRA as mentioned above.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-27 10:52         ` Ulrich Weigand
@ 2020-11-27 19:22           ` Maciej W. Rozycki
  2020-11-27 20:47             ` Maciej W. Rozycki
  2020-11-29 17:31             ` [PATCH v2 " Jeff Law
  0 siblings, 2 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-27 19:22 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches, Eric Botcazou, Jeff Law, Anders Magnusson

On Fri, 27 Nov 2020, Ulrich Weigand wrote:

> >  NB I find the reindentation resulting in `push_reload' awful, just as I 
> > do either version of the massive logical expression involved.  Perhaps we 
> > could factor these out into `static inline' functions sometime, and then 
> > have them split into individual returns within?
> 
> I'm generally hesitant to do a lot of changes to the reload code base
> at this stage.  The strategy rather is to move all remaining targets
> over to LRA and then simply delete reload :-)
> 
> Given that you're modernizing the vax target, I'm wondering if you
> shouldn't rather go all the way and move it over to LRA as well,
> then you wouldn't be affected by any remaining reload deficiencies.
> (The major hurdle so far was that LRA doesn't support CC0, but it
> looks like you're removing that anyway ...)

 I considered moving to LRA, but decided to make one step at a time, 
especially given the number of issues the VAX port has been suffering 
from.  For example there are cases evident from regression test failures 
where new pseudos are created past-reload.  That would require tracking 
down, and I think switching to LRA would best be made with cleaner test 
results so as not to introduce another variable into the picture.

 So I would consider it GCC 12 material, so that we have an actual release 
with the VAX port converted to MODE_CC, but still using reload.  I think 
it could make some backports easier too if NetBSD people wanted to do it.

> > +      && (strict_low
> > +	  || (subreg_lowpart_p (in)
> > +	      && (CONSTANT_P (SUBREG_REG (in))
> > +		  || GET_CODE (SUBREG_REG (in)) == PLUS
> > +		  || strict_low
> 
> If we do this, then that "|| strict_low" clause is now redundant. 

 Oh!  I noticed the redundancy (which was in the way of the extra 
condition I was about to add) and rewrote the expression so as to remove 
it, and looks like I then left the line in place.  Maybe I didn't save the 
final change in the editor or something.  Sigh!  Thanks for spotting it.

> > +	      && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER
> > +	      && reg_equiv_mem (REGNO (SUBREG_REG (in)))
> > +	      && (mode_dependent_address_p
> > +		  (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in))), 0),
> > +		   MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in)))))))))
> 
> I guess this is not incorrect, but I'm wondering if it would be
> *complete* -- there are other cases where reload replaces a pseudo
> with a MEM even where reg_equiv_mem is null.

 I wasn't aware of that.  What would be the usual scenario?

> That said, if it fixes the test suite errors you're seeing, it would
> probably be OK to go with just this minimal change -- unless we can
> just move to LRA as mentioned above.

 I've looked through the test results and indeed these suspicious ICEs 
remain:

.../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
.../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:27:1: internal compiler error: in change_address_1, at emit-rtl.c:2275

corresponding to:

FAIL: gcc.dg/pr83623.c (internal compiler error)
FAIL: gcc.dg/pr83623.c (test for excess errors)
FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (test for excess errors)

I'll investigate.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-27 19:22           ` Maciej W. Rozycki
@ 2020-11-27 20:47             ` Maciej W. Rozycki
  2020-11-27 20:50               ` [PATCH v3 " Maciej W. Rozycki
  2020-11-29 17:31             ` [PATCH v2 " Jeff Law
  1 sibling, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-27 20:47 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches, Eric Botcazou, Jeff Law, Anders Magnusson

On Fri, 27 Nov 2020, Maciej W. Rozycki wrote:

> > That said, if it fixes the test suite errors you're seeing, it would
> > probably be OK to go with just this minimal change -- unless we can
> > just move to LRA as mentioned above.
> 
>  I've looked through the test results and indeed these suspicious ICEs 
> remain:
> 
> .../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
> .../gcc/testsuite/gcc.dg/torture/vshuf-main.inc:27:1: internal compiler error: in change_address_1, at emit-rtl.c:2275

 I've double-checked these and this:

> corresponding to:
> 
> FAIL: gcc.dg/pr83623.c (internal compiler error)
> FAIL: gcc.dg/pr83623.c (test for excess errors)

comes from this insn:

(insn 17 14 145 (set (reg:SI 1 %r1)
        (zero_extract:SI (mem/c:SI (symbol_ref:SI ("x") <var_decl 0x7ffff7f80120 x>) [1 x+0 S4 A128])
            (const_int 16 [0x10])
            (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/pr83623.c":12:9 101 {*vax.md:805}
     (nil))

and this:

> FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (internal compiler error)
> FAIL: gcc.dg/torture/vshuf-v16qi.c   -O2  (test for excess errors)

likewise:

(insn 83 82 84 (set (reg:SI 5 %r5 [84])
        (zero_extract:SI (mem/c:SI (symbol_ref:SI ("b") <var_decl 0x7ffff7f801b0 b>) [0 b+0 S4 A128])
            (const_int 8 [0x8])
            (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/torture/vshuf-main.inc":28:1 101 {*vax.md:805}
     (nil))

So these are not related (and addressed with 22/31 BTW).

 I'll make the "|| strict_low" update then and push this change along with 
the rest once all the verification has completed, presumably this coming 
Monday.

 Thanks for your review!

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH v3 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-27 20:47             ` Maciej W. Rozycki
@ 2020-11-27 20:50               ` Maciej W. Rozycki
  2020-11-30 18:51                 ` Jeff Law
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-27 20:50 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches, Eric Botcazou, Jeff Law, Anders Magnusson

From: Matt Thomas <matt@3am-software.com>

Fix an ICE with the handling of RTL expressions like:

(subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67])
                    (const_int 4 [0x4]))
                (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59]))
            (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0)

that causes the compilation of libgomp to fail:

during RTL pass: reload
.../libgomp/ordered.c: In function 'GOMP_doacross_wait':
.../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
  507 | }
      | ^
0x10a3462b change_address_1
	.../gcc/emit-rtl.c:2275
0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
	.../gcc/emit-rtl.c:2409
0x10ae2993 alter_subreg(rtx_def**, bool)
	.../gcc/final.c:3368
0x10ae25cf cleanup_subreg_operands(rtx_insn*)
	.../gcc/final.c:3322
0x110922a3 reload(rtx_insn*, int)
	.../gcc/reload1.c:1232
0x10de2bf7 do_reload
	.../gcc/ira.c:5812
0x10de3377 execute
	.../gcc/ira.c:5986

in a `vax-netbsdelf' build, where an attempt is made to change the mode
of the contained memory reference to the mode of the containing SUBREG.
Such RTL expressions are produced by the VAX shift and rotate patterns
(`ashift', `ashiftrt', `rotate', `rotatert') where the count operand
always has the QI mode regardless of the mode, either SI or DI, of the
datum shifted or rotated.

Such a mode change cannot work where the memory reference uses the
indexed addressing mode, where a multiplier is implied that in the VAX
ISA depends on the width of the memory access requested and therefore
changing the machine mode would change the address calculation as well.

Avoid the attempt then by forcing the reload of any SUBREGs containing
a mode-dependent memory reference, also fixing these regressions:

FAIL: gcc.c-torture/compile/pr46883.c   -Os  (internal compiler error)
FAIL: gcc.c-torture/compile/pr46883.c   -Os  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
FAIL: gcc.dg/20050629-1.c (internal compiler error)
FAIL: gcc.dg/20050629-1.c (test for excess errors)
FAIL: c-c++-common/torture/pr53505.c   -Os  (internal compiler error)
FAIL: c-c++-common/torture/pr53505.c   -Os  (test for excess errors)
FAIL: gfortran.dg/coarray_failed_images_1.f08   -Os  (internal compiler error)
FAIL: gfortran.dg/coarray_stopped_images_1.f08   -Os  (internal compiler error)

With test case #0 included it causes a reload with:

(insn 15 14 16 4 (set (reg:SI 31)
        (ashift:SI (const_int 1 [0x1])
            (subreg:QI (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) 0))) "pr58901-0.c":15:12 94 {ashlsi3}
     (expr_list:REG_DEAD (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
        (nil)))

as follows:

Reloads for insn # 15
Reload 0: reload_in (SI) = (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
	ALL_REGS, RELOAD_FOR_INPUT (opnum = 2)
	reload_in_reg: (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
	reload_reg_rtx: (reg:SI 5 %r5)

resulting in:

(insn 37 14 15 4 (set (reg:SI 5 %r5)
        (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:25 i ] [25])
                        (const_int 4 [0x4]))
                    (reg/v/f:SI 4 %r4 [orig:29 s ] [29]))
                (const_int 4 [0x4])) [1 MEM[(int *)s_8(D) + 4B + _5 * 4]+0 S4 A32])) "pr58901-0.c":15:12 12 {movsi_2}
     (nil))
(insn 15 37 16 4 (set (reg:SI 2 %r2 [31])
        (ashift:SI (const_int 1 [0x1])
            (reg:QI 5 %r5))) "pr58901-0.c":15:12 94 {ashlsi3}
     (nil))

and assembly like:

.L3:
	movl 4(%r4)[%r1],%r5
	ashl %r5,$1,%r2
	xorl2 %r2,%r0
	incl %r1
	cmpl %r1,%r3
	jneq .L3

produced for the loop, providing optimization has been enabled.  

Likewise with test case #1 the reload of:

(insn 17 16 18 4 (set (reg:SI 34)
        (and:SI (subreg:SI (reg/v:DI 27 [ t ]) 4)
            (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
     (expr_list:REG_DEAD (reg/v:DI 27 [ t ])
        (nil)))

is as follows:

Reloads for insn # 17
Reload 0: reload_in (DI) = (reg/v:DI 27 [ t ])
	reload_out (SI) = (reg:SI 2 %r2 [34])
	ALL_REGS, RELOAD_OTHER (opnum = 0)
	reload_in_reg: (reg/v:DI 27 [ t ])
	reload_out_reg: (reg:SI 2 %r2 [34])
	reload_reg_rtx: (reg:DI 4 %r4)

resulting in:

(insn 40 16 17 4 (set (reg:DI 4 %r4)
        (mem/c:DI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:26 i ] [26])
                    (const_int 8 [0x8]))
                (reg/v/f:SI 3 %r3 [orig:30 s ] [30])) [1 MEM[(const struct s *)s_13(D) + _7 * 8]+0 S8 A32])) "pr58901-1.c":18:20 11 {movdi}
     (nil))
(insn 17 40 41 4 (set (reg:SI 4 %r4)
        (and:SI (reg:SI 5 %r5 [+4 ])
            (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
     (nil))

and assembly like:

.L3:
	movq (%r3)[%r1],%r4
	bicl3 $-2,%r5,%r4
	addl2 %r4,%r0
	jaoblss %r0,%r1,.L3

First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.

2020-11-27  Matt Thomas  <matt@3am-software.com>
	    Maciej W. Rozycki  <macro@linux-mips.org>

	gcc/
	PR target/58901
	* reload.c (push_reload): Also reload the inner expression of a 
	SUBREG for pseudos associated with a mode-dependent memory 
	reference.
	(find_reloads): Force a reload likewise.

2020-11-27  Maciej W. Rozycki  <macro@linux-mips.org>

	gcc/testsuite/
	PR target/58901
	* gcc.c-torture/compile/pr58901-0.c: New test.
	* gcc.c-torture/compile/pr58901-1.c: New test.
---
 gcc/reload.c                                    |  104 +++++++++++++++---------
 gcc/testsuite/gcc.c-torture/compile/pr58901-0.c |   17 +++
 gcc/testsuite/gcc.c-torture/compile/pr58901-1.c |   21 ++++
 3 files changed, 106 insertions(+), 36 deletions(-)

Index: gcc/gcc/reload.c
===================================================================
--- gcc.orig/gcc/reload.c
+++ gcc/gcc/reload.c
@@ -1043,53 +1043,72 @@ push_reload (rtx in, rtx out, rtx *inloc
      Also reload the inner expression if it does not require a secondary
      reload but the SUBREG does.
 
-     Finally, reload the inner expression if it is a register that is in
+     Also reload the inner expression if it is a register that is in
      the class whose registers cannot be referenced in a different size
      and M1 is not the same size as M2.  If subreg_lowpart_p is false, we
      cannot reload just the inside since we might end up with the wrong
      register class.  But if it is inside a STRICT_LOW_PART, we have
-     no choice, so we hope we do get the right register class there.  */
+     no choice, so we hope we do get the right register class there.
+
+     Finally, reload the inner expression if it is a pseudo that will
+     become a MEM and the MEM has a mode-dependent address, as in that
+     case we obviously cannot change the mode of the MEM to that of the
+     containing SUBREG as that would change the interpretation of the
+     address.  */
 
   scalar_int_mode inner_mode;
   if (in != 0 && GET_CODE (in) == SUBREG
-      && (subreg_lowpart_p (in) || strict_low)
       && targetm.can_change_mode_class (GET_MODE (SUBREG_REG (in)),
 					inmode, rclass)
       && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (in))]
-      && (CONSTANT_P (SUBREG_REG (in))
-	  || GET_CODE (SUBREG_REG (in)) == PLUS
-	  || strict_low
-	  || (((REG_P (SUBREG_REG (in))
-		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
-	       || MEM_P (SUBREG_REG (in)))
-	      && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-		  || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
-		      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)),
-						 &inner_mode)
-		      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
-		      && paradoxical_subreg_p (inmode, inner_mode)
-		      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
-		  || (WORD_REGISTER_OPERATIONS
-		      && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-		      && (known_equal_after_align_down
-			  (GET_MODE_SIZE (inmode) - 1,
-			   GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1,
-			   UNITS_PER_WORD)))))
-	  || (REG_P (SUBREG_REG (in))
-	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-	      /* The case where out is nonzero
-		 is handled differently in the following statement.  */
-	      && (out == 0 || subreg_lowpart_p (in))
-	      && (complex_word_subreg_p (inmode, SUBREG_REG (in))
-		  || !targetm.hard_regno_mode_ok (subreg_regno (in), inmode)))
-	  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
-	      && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
-					  SUBREG_REG (in))
-		  == NO_REGS))
+      && (strict_low
+	  || (subreg_lowpart_p (in)
+	      && (CONSTANT_P (SUBREG_REG (in))
+		  || GET_CODE (SUBREG_REG (in)) == PLUS
+		  || (((REG_P (SUBREG_REG (in))
+			&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
+		       || MEM_P (SUBREG_REG (in)))
+		      && (paradoxical_subreg_p (inmode,
+						GET_MODE (SUBREG_REG (in)))
+			  || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
+			      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG
+								   (in)),
+							 &inner_mode)
+			      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
+			      && paradoxical_subreg_p (inmode, inner_mode)
+			      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
+			  || (WORD_REGISTER_OPERATIONS
+			      && partial_subreg_p (inmode,
+						   GET_MODE (SUBREG_REG (in)))
+			      && (known_equal_after_align_down
+				  (GET_MODE_SIZE (inmode) - 1,
+				   GET_MODE_SIZE (GET_MODE (SUBREG_REG
+							    (in))) - 1,
+				   UNITS_PER_WORD)))))
+		  || (REG_P (SUBREG_REG (in))
+		      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
+		      /* The case where out is nonzero
+			 is handled differently in the following statement.  */
+		      && (out == 0 || subreg_lowpart_p (in))
+		      && (complex_word_subreg_p (inmode, SUBREG_REG (in))
+			  || !targetm.hard_regno_mode_ok (subreg_regno (in),
+							  inmode)))
+		  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
+		      && (secondary_reload_class (1, rclass,
+						  GET_MODE (SUBREG_REG (in)),
+						  SUBREG_REG (in))
+			  == NO_REGS))
+		  || (REG_P (SUBREG_REG (in))
+		      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
+		      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
+						 GET_MODE (SUBREG_REG (in)),
+						 inmode))))
 	  || (REG_P (SUBREG_REG (in))
-	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
-					 GET_MODE (SUBREG_REG (in)), inmode))))
+	      && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER
+	      && reg_equiv_mem (REGNO (SUBREG_REG (in)))
+	      && (mode_dependent_address_p
+		  (XEXP (reg_equiv_mem (REGNO (SUBREG_REG (in))), 0),
+		   MEM_ADDR_SPACE (reg_equiv_mem (REGNO (SUBREG_REG (in)))))))))
     {
 #ifdef LIMIT_RELOAD_CLASS
       in_subreg_loc = inloc;
@@ -3157,6 +3176,19 @@ find_reloads (rtx_insn *insn, int replac
 				  && paradoxical_subreg_p (operand_mode[i],
 							   inner_mode)
 				  && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)))
+		      /* We must force a reload of a SUBREG's inner expression
+			 if it is a pseudo that will become a MEM and the MEM
+			 has a mode-dependent address, as in that case we
+			 obviously cannot change the mode of the MEM to that
+			 of the containing SUBREG as that would change the
+			 interpretation of the address.  */
+		      || (REG_P (operand)
+			  && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+			  && reg_equiv_mem (REGNO (operand))
+			  && (mode_dependent_address_p
+			      (XEXP (reg_equiv_mem (REGNO (operand)), 0),
+			       (MEM_ADDR_SPACE
+				(reg_equiv_mem (REGNO (operand)))))))
 		      )
 		    force_reload = 1;
 		}
Index: gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-0.c
@@ -0,0 +1,17 @@
+typedef signed int __attribute__ ((mode (SI))) int_t;
+
+struct s
+{
+  int_t n;
+  int_t c[];
+};
+
+int_t
+ashlsi (int_t x, const struct s *s)
+{
+  int_t i;
+
+  for (i = 0; i < s->n; i++)
+    x ^= 1 << s->c[i];
+  return x;
+}
Index: gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.c-torture/compile/pr58901-1.c
@@ -0,0 +1,21 @@
+typedef int __attribute__ ((mode (SI))) int_t;
+
+struct s
+{
+  int_t n;
+  int_t m : 1;
+  int_t l : 31;
+};
+
+int_t
+movdi (int_t x, const struct s *s)
+{
+  int_t i;
+
+  for (i = 0; i < x; i++)
+    {
+      const struct s t = s[i];
+      x += t.m ? 1 : 0;
+    }
+  return x;
+}

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 17:07   ` Maciej W. Rozycki
@ 2020-11-28 18:48     ` Paul Koning
  2020-12-09 14:06       ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Paul Koning @ 2020-11-28 18:48 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: GCC Patches



> On Nov 25, 2020, at 12:07 PM, Maciej W. Rozycki <macro@linux-mips.org> wrote:
> 
> On Mon, 23 Nov 2020, Paul Koning wrote:
> 
>>> ...
> 
>> I've hacked together a primitive newlib based "bare metal" execution 
>> test setup that uses SIMH, but it's not a particularly clean setup.  
>> And it hasn't been posted, I hope to be able to do that at some point.
> 
> Hmm, I gather those systems are able to run some kind of BSD Unix: don't 
> they support the r-commands which would allow you to run DejaGNU testing 
> with a realistic environment PDP-11 hardware would be usually used with, 
> possibly on actual hardware even?  I always feel a bit uneasy about the 
> accuracy of any simulation (having suffered from bugs in QEMU causing 
> false negatives in software verification).

Fair enough.  But SIMH is a full system emulator with a very large amount of history and expertise involved in its creation.  It's also known to run every PDP-11 OS and most diagnostics.  Yes, it certainly runs BSD 2.x; the reason I didn't use that approach is that I don't know it well. 

> While I would expect old BSD libc to miss some of the C language features 
> considered standard nowadays, I think at least the C GCC frontend runtime 
> (libgcc.a) and the test suite do not overall rely on their presence, and 
> any individual test cases that do can be easily excluded.
> 
>> Thanks for the fix.
> 
> I take it as an approval and will apply the change then along with the 
> rest of the series.  Thank you for your review.

I should have been explicit.  Yes, I approve that change, thanks.

	paul


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-27 19:22           ` Maciej W. Rozycki
  2020-11-27 20:47             ` Maciej W. Rozycki
@ 2020-11-29 17:31             ` Jeff Law
  1 sibling, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-29 17:31 UTC (permalink / raw)
  To: Maciej W. Rozycki, Ulrich Weigand
  Cc: gcc-patches, Eric Botcazou, Anders Magnusson



On 11/27/20 12:22 PM, Maciej W. Rozycki wrote:
> On Fri, 27 Nov 2020, Ulrich Weigand wrote:
>
>>>  NB I find the reindentation resulting in `push_reload' awful, just as I 
>>> do either version of the massive logical expression involved.  Perhaps we 
>>> could factor these out into `static inline' functions sometime, and then 
>>> have them split into individual returns within?
>> I'm generally hesitant to do a lot of changes to the reload code base
>> at this stage.  The strategy rather is to move all remaining targets
>> over to LRA and then simply delete reload :-)
>>
>> Given that you're modernizing the vax target, I'm wondering if you
>> shouldn't rather go all the way and move it over to LRA as well,
>> then you wouldn't be affected by any remaining reload deficiencies.
>> (The major hurdle so far was that LRA doesn't support CC0, but it
>> looks like you're removing that anyway ...)
>  I considered moving to LRA, but decided to make one step at a time, 
> especially given the number of issues the VAX port has been suffering 
> from.  For example there are cases evident from regression test failures 
> where new pseudos are created past-reload.  That would require tracking 
> down, and I think switching to LRA would best be made with cleaner test 
> results so as not to introduce another variable into the picture.
>
>  So I would consider it GCC 12 material, so that we have an actual release 
> with the VAX port converted to MODE_CC, but still using reload.  I think 
> it could make some backports easier too if NetBSD people wanted to do it.
That was my plan on H8 as well (switch to LRA next cycle).  I am aware
of one reload issue that the move away from cc0 triggers, but I'm
ignoring it for now.
Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-25 18:36 ` Maciej W. Rozycki
  2020-11-26 14:46   ` Ian Lance Taylor
@ 2020-11-29 17:56   ` Martin Sebor
  2020-12-07 14:25     ` Maciej W. Rozycki
  1 sibling, 1 reply; 117+ messages in thread
From: Martin Sebor @ 2020-11-29 17:56 UTC (permalink / raw)
  To: Maciej W. Rozycki, Ian Lance Taylor, gcc-patches; +Cc: Anders Magnusson

On 11/25/20 11:36 AM, Maciej W. Rozycki wrote:
> On Fri, 20 Nov 2020, Maciej W. Rozycki wrote:
> 
>>   These changes have been regression-tested throughout development with the
>> `vax-netbsdelf' target running NetBSD 9.0, using said VAXstation 4000/60,
>> which uses the Mariah implemementation of the VAX architecture.  The host
>> used was `powerpc64le-linux-gnu' and occasionally `x86_64-linux-gnu' as
>> well; changes outside the VAX backend were all natively bootstrapped and
>> regression-tested with both these hosts.
> 
>   I forgot to note that I have been going through this final verification
> with the native compiler and the `vax-netbsdelf' cross-compiler built with
> it both configured with `--disable-werror'.  This is due to a recent
> regression with the Go frontend causing a build error otherwise:
> 
> .../gcc/go/gofrontend/go-diagnostics.cc: In function 'std::string expand_message(const char*, va_list)':
> .../gcc/go/gofrontend/go-diagnostics.cc:110:61: error: '<anonymous>' may be used uninitialized [-Werror=maybe-uninitialized]
>    110 |                      "memory allocation failed in vasprintf");
>        |                                                             ^
> In file included from .../prev-powerpc64le-linux-gnu/libstdc++-v3/include/string:55,
>                   from .../gcc/go/go-system.h:34,
>                   from .../gcc/go/gofrontend/go-linemap.h:10,
>                   from .../gcc/go/gofrontend/go-diagnostics.h:10,
>                   from .../gcc/go/gofrontend/go-diagnostics.cc:7:
> .../prev-powerpc64le-linux-gnu/libstdc++-v3/include/bits/basic_string.h:525:7: note: by argument 3 of type 'const std::allocator<char>&' to 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with <template-parameter-2-1> = std::allocator<char>; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' declared here
>    525 |       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
>        |       ^~~~~~~~~~~~
> .../gcc/go/gofrontend/go-diagnostics.cc:110:61: note: '<anonymous>' declared here
>    110 |                      "memory allocation failed in vasprintf");
>        |                                                             ^
> cc1plus: all warnings being treated as errors
> make[3]: *** [.../gcc/go/Make-lang.in:242: go/go-diagnostics.o] Error 1
> 
> the cause for which I decided I could not afford the time to track down.
> Perhaps it has been fixed since, but mentioning it in case it has not.

I wouldn't expect to see this warning after r11-5073.  If it persists,
can you please open a bug and attach the translation unit to it?

Thanks
Martin

> 
>   Earlier verification iterations were done with `--enable-werror-always'.
> 
>    Maciej
> 


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns
  2020-11-21  4:05   ` Jeff Law
@ 2020-11-30 16:02     ` Maciej W. Rozycki
  2020-11-30 18:29       ` Jeff Law
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-11-30 16:02 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, Anders Magnusson, Paul Koning, Matt Thomas

On Fri, 20 Nov 2020, Jeff Law wrote:

> ps.  Yes, I skipped the insv/extv changes.  They're usually a rats nest
> of special cases.  We'll come back to them.

 I've thought of actually reducing the number of patterns to the minimum 
possible by folding the existing ones together, and then getting the 
alternatives sorted by fine-grained constraints at reload.

 There is that complication caused by INSV machine instruction preserving 
condition codes (understandably), so keeping it together with alternative 
code sequences that do set the codes in a single RTL insn would cause 
trouble with getting a matching insn for the comparison elimination pass.  
Or so I think.

 As you say, we can sort it later.  It's an optimisation only anyway, the 
VAX EXTV/EXTZV/INSV machine instructions are flexible enough to handle 
just about anything, except that reportedly at a slow pace, at least with 
some implementations (I'd have to review that NVAX manual for the details, 
but it's hefty 1022 pages).  So at worst we could use those instructions 
in all cases.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns
  2020-11-30 16:02     ` Maciej W. Rozycki
@ 2020-11-30 18:29       ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-30 18:29 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson, Paul Koning, Matt Thomas



On 11/30/20 9:02 AM, Maciej W. Rozycki wrote:
> On Fri, 20 Nov 2020, Jeff Law wrote:
>
>> ps.  Yes, I skipped the insv/extv changes.  They're usually a rats nest
>> of special cases.  We'll come back to them.
>  I've thought of actually reducing the number of patterns to the minimum 
> possible by folding the existing ones together, and then getting the 
> alternatives sorted by fine-grained constraints at reload.
That might work, but I've generally found insv/extv to be fairly painful
through the years, more because of limitations on the generic bits
rather than the target bits.

>
>  There is that complication caused by INSV machine instruction preserving 
> condition codes (understandably), so keeping it together with alternative 
> code sequences that do set the codes in a single RTL insn would cause 
> trouble with getting a matching insn for the comparison elimination pass.  
> Or so I think.
Yea.  I think that is (in general) not a well solved problem.  We have
similar issues on the H8 where we have multiple ways to implement
certain operations -- some of which set/clobber flags while others don't
touch them.  Depending on the context one form may be preferable to the
other.  I've punted this problem so far as I strongly suspect the gains
in handling this scenario well are marginal at best.

Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v3 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
  2020-11-27 20:50               ` [PATCH v3 " Maciej W. Rozycki
@ 2020-11-30 18:51                 ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-11-30 18:51 UTC (permalink / raw)
  To: Maciej W. Rozycki, Ulrich Weigand
  Cc: gcc-patches, Eric Botcazou, Anders Magnusson



On 11/27/20 1:50 PM, Maciej W. Rozycki wrote:
> From: Matt Thomas <matt@3am-software.com>
>
> Fix an ICE with the handling of RTL expressions like:
>
> (subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67])
>                     (const_int 4 [0x4]))
>                 (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59]))
>             (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0)
>
> that causes the compilation of libgomp to fail:
>
> during RTL pass: reload
> .../libgomp/ordered.c: In function 'GOMP_doacross_wait':
> .../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
>   507 | }
>       | ^
> 0x10a3462b change_address_1
> 	.../gcc/emit-rtl.c:2275
> 0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
> 	.../gcc/emit-rtl.c:2409
> 0x10ae2993 alter_subreg(rtx_def**, bool)
> 	.../gcc/final.c:3368
> 0x10ae25cf cleanup_subreg_operands(rtx_insn*)
> 	.../gcc/final.c:3322
> 0x110922a3 reload(rtx_insn*, int)
> 	.../gcc/reload1.c:1232
> 0x10de2bf7 do_reload
> 	.../gcc/ira.c:5812
> 0x10de3377 execute
> 	.../gcc/ira.c:5986
>
> in a `vax-netbsdelf' build, where an attempt is made to change the mode
> of the contained memory reference to the mode of the containing SUBREG.
> Such RTL expressions are produced by the VAX shift and rotate patterns
> (`ashift', `ashiftrt', `rotate', `rotatert') where the count operand
> always has the QI mode regardless of the mode, either SI or DI, of the
> datum shifted or rotated.
>
> Such a mode change cannot work where the memory reference uses the
> indexed addressing mode, where a multiplier is implied that in the VAX
> ISA depends on the width of the memory access requested and therefore
> changing the machine mode would change the address calculation as well.
>
> Avoid the attempt then by forcing the reload of any SUBREGs containing
> a mode-dependent memory reference, also fixing these regressions:
>
> FAIL: gcc.c-torture/compile/pr46883.c   -Os  (internal compiler error)
> FAIL: gcc.c-torture/compile/pr46883.c   -Os  (test for excess errors)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (internal compiler error)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (test for excess errors)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (internal compiler error)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (test for excess errors)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
> FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
> FAIL: gcc.dg/20050629-1.c (internal compiler error)
> FAIL: gcc.dg/20050629-1.c (test for excess errors)
> FAIL: c-c++-common/torture/pr53505.c   -Os  (internal compiler error)
> FAIL: c-c++-common/torture/pr53505.c   -Os  (test for excess errors)
> FAIL: gfortran.dg/coarray_failed_images_1.f08   -Os  (internal compiler error)
> FAIL: gfortran.dg/coarray_stopped_images_1.f08   -Os  (internal compiler error)
>
> With test case #0 included it causes a reload with:
>
> (insn 15 14 16 4 (set (reg:SI 31)
>         (ashift:SI (const_int 1 [0x1])
>             (subreg:QI (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) 0))) "pr58901-0.c":15:12 94 {ashlsi3}
>      (expr_list:REG_DEAD (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
>         (nil)))
>
> as follows:
>
> Reloads for insn # 15
> Reload 0: reload_in (SI) = (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
> 	ALL_REGS, RELOAD_FOR_INPUT (opnum = 2)
> 	reload_in_reg: (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
> 	reload_reg_rtx: (reg:SI 5 %r5)
>
> resulting in:
>
> (insn 37 14 15 4 (set (reg:SI 5 %r5)
>         (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:25 i ] [25])
>                         (const_int 4 [0x4]))
>                     (reg/v/f:SI 4 %r4 [orig:29 s ] [29]))
>                 (const_int 4 [0x4])) [1 MEM[(int *)s_8(D) + 4B + _5 * 4]+0 S4 A32])) "pr58901-0.c":15:12 12 {movsi_2}
>      (nil))
> (insn 15 37 16 4 (set (reg:SI 2 %r2 [31])
>         (ashift:SI (const_int 1 [0x1])
>             (reg:QI 5 %r5))) "pr58901-0.c":15:12 94 {ashlsi3}
>      (nil))
>
> and assembly like:
>
> .L3:
> 	movl 4(%r4)[%r1],%r5
> 	ashl %r5,$1,%r2
> 	xorl2 %r2,%r0
> 	incl %r1
> 	cmpl %r1,%r3
> 	jneq .L3
>
> produced for the loop, providing optimization has been enabled.  
>
> Likewise with test case #1 the reload of:
>
> (insn 17 16 18 4 (set (reg:SI 34)
>         (and:SI (subreg:SI (reg/v:DI 27 [ t ]) 4)
>             (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
>      (expr_list:REG_DEAD (reg/v:DI 27 [ t ])
>         (nil)))
>
> is as follows:
>
> Reloads for insn # 17
> Reload 0: reload_in (DI) = (reg/v:DI 27 [ t ])
> 	reload_out (SI) = (reg:SI 2 %r2 [34])
> 	ALL_REGS, RELOAD_OTHER (opnum = 0)
> 	reload_in_reg: (reg/v:DI 27 [ t ])
> 	reload_out_reg: (reg:SI 2 %r2 [34])
> 	reload_reg_rtx: (reg:DI 4 %r4)
>
> resulting in:
>
> (insn 40 16 17 4 (set (reg:DI 4 %r4)
>         (mem/c:DI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:26 i ] [26])
>                     (const_int 8 [0x8]))
>                 (reg/v/f:SI 3 %r3 [orig:30 s ] [30])) [1 MEM[(const struct s *)s_13(D) + _7 * 8]+0 S8 A32])) "pr58901-1.c":18:20 11 {movdi}
>      (nil))
> (insn 17 40 41 4 (set (reg:SI 4 %r4)
>         (and:SI (reg:SI 5 %r5 [+4 ])
>             (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
>      (nil))
>
> and assembly like:
>
> .L3:
> 	movq (%r3)[%r1],%r4
> 	bicl3 $-2,%r5,%r4
> 	addl2 %r4,%r0
> 	jaoblss %r0,%r1,.L3
>
> First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.
>
> 2020-11-27  Matt Thomas  <matt@3am-software.com>
> 	    Maciej W. Rozycki  <macro@linux-mips.org>
>
> 	gcc/
> 	PR target/58901
> 	* reload.c (push_reload): Also reload the inner expression of a 
> 	SUBREG for pseudos associated with a mode-dependent memory 
> 	reference.
> 	(find_reloads): Force a reload likewise.
>
> 2020-11-27  Maciej W. Rozycki  <macro@linux-mips.org>
>
> 	gcc/testsuite/
> 	PR target/58901
> 	* gcc.c-torture/compile/pr58901-0.c: New test.
> 	* gcc.c-torture/compile/pr58901-1.c: New test.
So one could make the argument that the (subreg (mem)) should never have
been generated in the first place.   I'm guessing they ultimately stem
from using QImode for the shift count.

The mode for the shift count has always been a bit controversial.  
We've got some ports that use QImode similar to the vax and others that
use the target's most natural mode, even if it's wider than what the
target really needs.  I can't offhand recall if there was a general
consensus on the best way for a target to handle this.

I'm certain there's other problems in the reloading of mode dependent
addresses.  See 66087 on the m68k.  This patch doesn't address that
issue (I was hoping it would, but such is life).  I'm not too inclined
to have folks chasing these issues though as reload (IMHO) should be on
the chopping block for gcc-12.

My overall thought WRT this patch is similar to Ulrich's.  Let's go with
it even though we know it's not necessarily 100% complete.  We can have
(subreg (mem)) coming into reload as say from 66087.  We may have other
ways where reload replaces a pseudo with a mem that aren't necessarily
caught here.

Jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* [PATCH v2 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE
  2020-11-21  4:25   ` Jeff Law
@ 2020-12-03  3:50     ` Maciej W. Rozycki
  2020-12-03 22:20       ` Jeff Law
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-03  3:50 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, Anders Magnusson, Paul Koning, Matt Thomas

VAX has interlocked branch instructions used for atomic operations and
we want to have them wrapped in UNSPEC_VOLATILE so as not to have code
carried across.  This however breaks with jump optimization and leads
to an ICE in the build of libbacktrace like:

.../libbacktrace/mmap.c:190:1: internal compiler error: in fixup_reorder_chain, at cfgrtl.c:3934
  190 | }
      | ^
0x1087d46b fixup_reorder_chain
	.../gcc/cfgrtl.c:3934
0x1087f29f cfg_layout_finalize()
	.../gcc/cfgrtl.c:4447
0x1087c74f execute
	.../gcc/cfgrtl.c:3662

on RTL like:

(jump_insn 18 17 150 4 (unspec_volatile [
            (set (pc)
                (if_then_else (eq (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
                            (const_int 1 [0x1])
                            (const_int 0 [0]))
                        (const_int 1 [0x1]))
                    (label_ref 20)
                    (pc)))
            (set (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
                    (const_int 1 [0x1])
                    (const_int 0 [0]))
                (const_int 1 [0x1]))
        ] 101) ".../libbacktrace/mmap.c":135:14 158 {jbbssisi}
     (nil)
 -> 20)

when those branches are enabled with a follow-up change.  Also showing
with:

FAIL: gcc.dg/pr61756.c (internal compiler error)

Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
branches from being removed as they won't be accepted by `onlyjump_p',
we just need to let them through.

	gcc/
	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
	UNSPEC_VOLATILE.
	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
---
On Fri, 20 Nov 2020, Jeff Law wrote:

> > Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
> > also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
> > branches from being removed as they won't be accepted by `onlyjump_p',
> > we just need to let them through.
> >
> > 	gcc/
> > 	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
> > 	UNSPEC_VOLATILE.
> > 	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
> I've got some concerns that there may be users of pc_set where handling
> UNSPECs would be undesirable.  For example the uses in cfgcleanup.

 I've gone through the use of `pc_set' and `any_condjump_p' in detail 
then.  Mind that I wouldn't claim expertise with this stuff, just common 
sense backed with documentation and source code available.

 It appears safe to me though, as the really dangerous cases where a jump 
is to be removed, in `thread_jump' and `outgoing_edges_match', are guarded 
with calls to `onlyjump_p' (the reference to which from the description of 
`any_condjump_p' making a promise it will guard the relevant cases is what 
made me pretty confident with my change being technically correct), which 
will reject any jumps wrapped into UNSPEC_VOLATILE or even UNSPEC (though 
arguably the latter case might be an overkill, and we could loosen that 
restriction) on the premise of failing `single_set', which only accepts a 
SET, possibly wrapped into a PARALLEL.

 Similarly with branch deletion in `cfg_layout_redirect_edge_and_branch' 
and attempted transformations using `cond_exec_get_condition'.

 Those `pc_set' calls that you mention are then only used once the 
containing code has been qualified with `onlyjump_p', so they won't be 
ever called with branches wrapped into UNSPEC_VOLATILE.  Likewise the 
`pc_set' calls in `cprop_jump' and `bypass_block'.

 The calls in `try_optimize_cfg' trying to convert a conditional branch 
into a corresponding conditional return (necessary to analyse of course 
though not relevant for the VAX; oh, how I long for the Z80) both rely on 
`redirect_jump' and possibly `invert_jump', and they're supposed to fail 
if a suitably modified original rtx cannot be matched with any RTL pattern 
(though AFAICS `redirect_exp_1' will just fail due to the lack of explicit 
UNSPEC_VOLATILE/UNSPEC support and so will `invert_jump' as it relies on 
it too).

 Except for one case the use in icvt appear safe to me: all legs except 
for ones calling into `dead_or_predicable' refer to `onlyjump_p'.  Then in 
`dead_or_predicable' we have two cases, NCE and CE.  The NCE one there is 
safe due to `can_move_insns_across' rejecting the move in the case of any 
UNSPEC_VOLATILE insn in either block.  The CE one isn't because ultimately 
it will delete the jump without validating it with `onlyjump_p' AFAICT.

 This will not affect VAX as it doesn't have conditional execution, and is 
not a fault in my change.  I think it needs fixing though, and I will post 
a patch separately, along with a minor clean-up in this area.

 In `force_nonfallthru_and_redirect' we have `gcc_assert (redirected)' and 
this may well trigger sometime.  Perhaps we need to make `redirect_jump' 
understand UNSPEC_VOLATILE/UNSPEC?  WDYT?

 Finally I feel like we ought to avoid loop unrolling with the relevant 
jumps as pasting the body of a loop multiple times within is semantically 
equivalent to jump deletion (between the iterations unrolled) even though 
we do not physically delete the RTL insn, so it needs to be guarded with 
`onlyjump_p', and to me it does not appear to.  I'll post a proposed 
change along with the other ones in a small series for easier reference.

 I suspect (though I'm not strongly confident) this change may not affect 
any actual code produced across our targets.  If it does, then I think we 
need to analyse individual cases and see how to proceed.  Otherwise I 
think we want the change for the sake of internal consistency.

 I won't be getting into further details of each case I have analysed.  I 
have ended up with five patches that add missing `onlyjump_p' calls, also 
for `any_uncondjump_p', which I think needs to be protected likewise, and 
actually already is in several places, making me feel pretty confident the 
remaining two are merely oversights.  I left cases across backend code 
intact under the assumption that they know what they are doing, e.g. 
because the respective backends have no jumps with side effects defined.

 With these extra patches I think we can safely proceed with my original 
change if not for an update to `redirect_jump' mentioned above.  The more 
I think about it the more I am convinced it would be a reasonable update 
to make.  I'll experiment with it, but I don't think it should ultimately 
be a showstopper for the change being reviewed here.

> Would it make sense to have the handling of UNSPECs be conditional so
> that we don't get unexpected jump threading, cross jumping, etc?

 So for the sake of this consideration I actually made such a change (for 
`pc_set' and `any_condjump_p'), applying the extra condition mechanically 
throughut our code and making it `true' for the equivalent of the original 
change right away where it was obvious to me it did not matter.  Then I 
went through the remaining ~50 cases in detail flipping the condition to 
`true' as I ticked off cases found harmless and finally came up with the 
conclusion above.  If any new dangerous cases arise, then I think they 
need to be guarded as appropriate, with `onlyjump_p' for deletions and 
`can_move_insns_across' for reordering.

 My overall view is with jumps wrapped into plain UNSPECs the middle end 
ought to be allowed to do whatever it wishes, it's an annotation really if 
the rtx within can be usefully interpreted.  While with UNSPEC_VOLATILEs 
obviously the usual rules for a barrier apply, i.e. the jump must not be 
deleted or code carried across it.  I think however that the target label 
is allowed to be redirected if we can prove (which I believe we do) that 
the resulting code is semantically equivalent, e.g. a conditional jump to 
an unconditional one.  And the condition is allowed to be reversed as long 
as, obviously, the backend has provided a definition for a corresponding 
reverse UNSPEC_VOLATILE branch.  Physical duplication (cf. `rotate_loop') 
is allowed too.

 I'll post the six patches mentioned shortly once I have written their 
descriptions.  Here's an update to 08/31 with a clarification WRT 
`onlyjump_p' for `any_uncondjump_p'; no functional change.

  Maciej

Changes from v1:

- Update `any_uncondjump_p' description.
---
 gcc/jump.c |   24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

Index: gcc/gcc/jump.c
===================================================================
--- gcc.orig/gcc/jump.c
+++ gcc/gcc/jump.c
@@ -850,9 +850,17 @@ pc_set (const rtx_insn *insn)
   pat = PATTERN (insn);
 
   /* The set is allowed to appear either as the insn pattern or
-     the first set in a PARALLEL.  */
-  if (GET_CODE (pat) == PARALLEL)
-    pat = XVECEXP (pat, 0, 0);
+     the first set in a PARALLEL, UNSPEC or UNSPEC_VOLATILE.  */
+  switch (GET_CODE (pat))
+    {
+    case PARALLEL:
+    case UNSPEC:
+    case UNSPEC_VOLATILE:
+      pat = XVECEXP (pat, 0, 0);
+      break;
+    default:
+      break;
+    }
   if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
     return pat;
 
@@ -860,7 +868,9 @@ pc_set (const rtx_insn *insn)
 }
 
 /* Return true when insn is an unconditional direct jump,
-   possibly bundled inside a PARALLEL.  */
+   possibly bundled inside a PARALLEL, UNSPEC or UNSPEC_VOLATILE.
+   The instruction may have various other effects so before removing the jump
+   you must verify onlyjump_p.  */
 
 int
 any_uncondjump_p (const rtx_insn *insn)
@@ -876,9 +886,9 @@ any_uncondjump_p (const rtx_insn *insn)
 }
 
 /* Return true when insn is a conditional jump.  This function works for
-   instructions containing PC sets in PARALLELs.  The instruction may have
-   various other effects so before removing the jump you must verify
-   onlyjump_p.
+   instructions containing PC sets in PARALLELs, UNSPECs or UNSPEC_VOLATILEs.
+   The instruction may have various other effects so before removing the jump
+   you must verify onlyjump_p.
 
    Note that unlike condjump_p it returns false for unconditional jumps.  */
 

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH v2 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE
  2020-12-03  3:50     ` [PATCH v2 " Maciej W. Rozycki
@ 2020-12-03 22:20       ` Jeff Law
  0 siblings, 0 replies; 117+ messages in thread
From: Jeff Law @ 2020-12-03 22:20 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gcc-patches, Anders Magnusson, Paul Koning, Matt Thomas



On 12/2/20 8:50 PM, Maciej W. Rozycki wrote:
> VAX has interlocked branch instructions used for atomic operations and
> we want to have them wrapped in UNSPEC_VOLATILE so as not to have code
> carried across.  This however breaks with jump optimization and leads
> to an ICE in the build of libbacktrace like:
>
> .../libbacktrace/mmap.c:190:1: internal compiler error: in fixup_reorder_chain, at cfgrtl.c:3934
>   190 | }
>       | ^
> 0x1087d46b fixup_reorder_chain
> 	.../gcc/cfgrtl.c:3934
> 0x1087f29f cfg_layout_finalize()
> 	.../gcc/cfgrtl.c:4447
> 0x1087c74f execute
> 	.../gcc/cfgrtl.c:3662
>
> on RTL like:
>
> (jump_insn 18 17 150 4 (unspec_volatile [
>             (set (pc)
>                 (if_then_else (eq (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
>                             (const_int 1 [0x1])
>                             (const_int 0 [0]))
>                         (const_int 1 [0x1]))
>                     (label_ref 20)
>                     (pc)))
>             (set (zero_extract:SI (mem/v:SI (reg/f:SI 23 [ _2 ]) [-1  S4 A32])
>                     (const_int 1 [0x1])
>                     (const_int 0 [0]))
>                 (const_int 1 [0x1]))
>         ] 101) ".../libbacktrace/mmap.c":135:14 158 {jbbssisi}
>      (nil)
>  -> 20)
>
> when those branches are enabled with a follow-up change.  Also showing
> with:
>
> FAIL: gcc.dg/pr61756.c (internal compiler error)
>
> Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
> also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
> branches from being removed as they won't be accepted by `onlyjump_p',
> we just need to let them through.
>
> 	gcc/
> 	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
> 	UNSPEC_VOLATILE.
> 	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
> ---
> On Fri, 20 Nov 2020, Jeff Law wrote:
>
>>> Handle branches wrapped in UNSPEC_VOLATILE then and, for consistency,
>>> also in UNSPEC.  The presence of UNSPEC_VOLATILE will prevent such
>>> branches from being removed as they won't be accepted by `onlyjump_p',
>>> we just need to let them through.
>>>
>>> 	gcc/
>>> 	* jump.c (pc_set): Also accept a jump wrapped in UNSPEC or
>>> 	UNSPEC_VOLATILE.
>>> 	(any_uncondjump_p, any_condjump_p): Update comment accordingly.
>> I've got some concerns that there may be users of pc_set where handling
>> UNSPECs would be undesirable.  For example the uses in cfgcleanup.
>  I've gone through the use of `pc_set' and `any_condjump_p' in detail 
> then.  Mind that I wouldn't claim expertise with this stuff, just common 
> sense backed with documentation and source code available.
>
>  It appears safe to me though, as the really dangerous cases where a jump 
> is to be removed, in `thread_jump' and `outgoing_edges_match', are guarded 
> with calls to `onlyjump_p' (the reference to which from the description of 
> `any_condjump_p' making a promise it will guard the relevant cases is what 
> made me pretty confident with my change being technically correct), which 
> will reject any jumps wrapped into UNSPEC_VOLATILE or even UNSPEC (though 
> arguably the latter case might be an overkill, and we could loosen that 
> restriction) on the premise of failing `single_set', which only accepts a 
> SET, possibly wrapped into a PARALLEL.
>
>  Similarly with branch deletion in `cfg_layout_redirect_edge_and_branch' 
> and attempted transformations using `cond_exec_get_condition'.
>
>  Those `pc_set' calls that you mention are then only used once the 
> containing code has been qualified with `onlyjump_p', so they won't be 
> ever called with branches wrapped into UNSPEC_VOLATILE.  Likewise the 
> `pc_set' calls in `cprop_jump' and `bypass_block'.
>
>  The calls in `try_optimize_cfg' trying to convert a conditional branch 
> into a corresponding conditional return (necessary to analyse of course 
> though not relevant for the VAX; oh, how I long for the Z80) both rely on 
> `redirect_jump' and possibly `invert_jump', and they're supposed to fail 
> if a suitably modified original rtx cannot be matched with any RTL pattern 
> (though AFAICS `redirect_exp_1' will just fail due to the lack of explicit 
> UNSPEC_VOLATILE/UNSPEC support and so will `invert_jump' as it relies on 
> it too).
>
>  Except for one case the use in icvt appear safe to me: all legs except 
> for ones calling into `dead_or_predicable' refer to `onlyjump_p'.  Then in 
> `dead_or_predicable' we have two cases, NCE and CE.  The NCE one there is 
> safe due to `can_move_insns_across' rejecting the move in the case of any 
> UNSPEC_VOLATILE insn in either block.  The CE one isn't because ultimately 
> it will delete the jump without validating it with `onlyjump_p' AFAICT.
>
>  This will not affect VAX as it doesn't have conditional execution, and is 
> not a fault in my change.  I think it needs fixing though, and I will post 
> a patch separately, along with a minor clean-up in this area.
>
>  In `force_nonfallthru_and_redirect' we have `gcc_assert (redirected)' and 
> this may well trigger sometime.  Perhaps we need to make `redirect_jump' 
> understand UNSPEC_VOLATILE/UNSPEC?  WDYT?
I'd lean against this.  In theory, we're just talking about redirecting
a branch.  But targets tend to add the UNSPECs when there's something
going on that we can't really expose and there isn't a good way to tell
the generic bits that direction is, or is not OK.


>
>  Finally I feel like we ought to avoid loop unrolling with the relevant 
> jumps as pasting the body of a loop multiple times within is semantically 
> equivalent to jump deletion (between the iterations unrolled) even though 
> we do not physically delete the RTL insn, so it needs to be guarded with 
> `onlyjump_p', and to me it does not appear to.  I'll post a proposed 
> change along with the other ones in a small series for easier reference.
I'd tend to agree.

> ould it make sense to have the handling of UNSPECs be conditional so
>> that we don't get unexpected jump threading, cross jumping, etc?
>  So for the sake of this consideration I actually made such a change (for 
> `pc_set' and `any_condjump_p'), applying the extra condition mechanically 
> throughut our code and making it `true' for the equivalent of the original 
> change right away where it was obvious to me it did not matter.  Then I 
> went through the remaining ~50 cases in detail flipping the condition to 
> `true' as I ticked off cases found harmless and finally came up with the 
> conclusion above.  If any new dangerous cases arise, then I think they 
> need to be guarded as appropriate, with `onlyjump_p' for deletions and 
> `can_move_insns_across' for reordering.
>
>  My overall view is with jumps wrapped into plain UNSPECs the middle end 
> ought to be allowed to do whatever it wishes, it's an annotation really if 
> the rtx within can be usefully interpreted.  While with UNSPEC_VOLATILEs 
> obviously the usual rules for a barrier apply, i.e. the jump must not be 
> deleted or code carried across it.  I think however that the target label 
> is allowed to be redirected if we can prove (which I believe we do) that 
> the resulting code is semantically equivalent, e.g. a conditional jump to 
> an unconditional one.  And the condition is allowed to be reversed as long 
> as, obviously, the backend has provided a definition for a corresponding 
> reverse UNSPEC_VOLATILE branch.  Physical duplication (cf. `rotate_loop') 
> is allowed too.
The counter case would be a port that inserts its own long branch
handling stubs and then might use UNSPECs to prevent the optimizers from
scrambling things again.  I'm not aware of this actually happening in
our sources, but it's the first case that comes to mind.


>
>  I'll post the six patches mentioned shortly once I have written their 
> descriptions.  Here's an update to 08/31 with a clarification WRT 
> `onlyjump_p' for `any_uncondjump_p'; no functional change.
>
>   Maciej
>
> Changes from v1:
>
> - Update `any_uncondjump_p' description.
> ---
>  gcc/jump.c |   24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)
OK
jeff


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 31/31] PR target/95294: VAX: Add test cases for MODE_CC representation
  2020-11-21  4:08   ` Jeff Law
@ 2020-12-05 18:40     ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-05 18:40 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, Anders Magnusson, Paul Koning, Matt Thomas

On Fri, 20 Nov 2020, Jeff Law wrote:

> Sweet.  OK once the prereqs are all ACK'd.

 Thank you for your review.  I have applied all the changes now, as posted 
in their most recent versions, except for 01/31 where I have noticed an 
anomaly in the included gcc/testsuite/gcc.c-torture/compile/pr58901-?.c 
test cases where the typedefs have been mistakenly swapped between them 
(obviously I meant to use `signed int' for the test case using a bit-field 
and not the other one, as otherwise the `signed' qualifier is redundant).  
I have adjusted the typedefs then, and committed an updated version as 
obviously correct (I double-checked they both still fail in the absence of 
the associated code update).

 While doing that I realised that "bit-field" is the correct spelling of 
the term both with the ISO C standard and the VAX ISA documentation, and 
also our predominantly used version in preference to "bitfield".  I have 
updated all the commit messages accordingly then; there have been no new 
use cases in actual change bodies, so no change there.

 I'll yet get through the discussions and see if there is anything I would 
like to comment on that I missed.  That may not be today though.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-29 17:56   ` Martin Sebor
@ 2020-12-07 14:25     ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-07 14:25 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Ian Lance Taylor, gcc-patches, Anders Magnusson

On Sun, 29 Nov 2020, Martin Sebor wrote:

> > Perhaps it has been fixed since, but mentioning it in case it has not.
> 
> I wouldn't expect to see this warning after r11-5073.  If it persists,
> can you please open a bug and attach the translation unit to it?

 Indeed, the issue has gone now, now that I have pushed the VAX changes 
and rebuilt a refreshed tree.  Thanks for looking into it.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-26 18:08                   ` Martin Husemann
@ 2020-12-08 14:38                     ` Maciej W. Rozycki
  2020-12-08 15:22                       ` Martin Husemann
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-08 14:38 UTC (permalink / raw)
  To: Martin Husemann, Tobias Burnus
  Cc: Joseph Myers, Thomas Koenig, Anders Magnusson, gcc-patches, fortran

On Thu, 26 Nov 2020, Martin Husemann wrote:

> >  The VAX/NetBSD port however does use hardware FP in their libm as far as 
> > I can tell, so I guess it would be reasonable for libgfortran to do so as 
> > well.  I haven't checked how correct their implementation actually is, but 
> > barring evidence otherwise I would assume they did the right thing.  
> 
> It does, but it is not totally correct in all places (due to gcc issues
> some parts have not received good testing, and others clearly are broken,
> eg. when tables are used that have not been adjusted for the different
> limits in VAX float/double formats).

 I have realised that with my VAX/Linux effort, more than 10 years ago, I 
did not encounter such issues, and I did port all the GCC components the 
compiler provided at the time (although the port of libjava could have 
been only partially functional as I didn't properly verify the IEEE<->VAX 
FP conversion stubs I have necessarily implemented), though what chose was 
4.1.2 rather than the most recent version (to avoid the need to port NPTL 
right away).  I should have tripped over this issue then, but I did not.

 So with the objective of this effort out of the way I have now looked 
into what happened with libgfortran here and realised that the cause of 
the compilation error was an attempt to provide a standard ISO C function 
missing from NetBSD's libc or libm (even though it's declared).  Indeed:

$ grep tgamma usr/include/math.h
double	tgamma(double);
float	tgammaf(float);
long double	tgammal(long double);
$ readelf -s usr/lib/libc.so usr/lib/libm.so usr/lib/libc.a usr/lib/libm.a | grep tgamma
$ 

So clearly something went wrong there and I think it's that that has to be 
fixed rather than the fallback implementations in libgfortran (which I 
gather have been only provided for legacy systems that do not implement a 
full ISO C environment and are no longer maintained).  I suspect that once 
this function (and any other ones that may be missing) has been supplied 
by the system libraries libgfortran will just work out of the box.

 Here's the full list of math functions that the `configure' script in 
libgfortran reports as missing:

checking for acosl... no
checking for acoshf... no
checking for acoshl... no
checking for asinl... no
checking for asinhf... no
checking for asinhl... no
checking for atan2l... no
checking for atanl... no
checking for atanhl... no
checking for cosl... no
checking for coshl... no
checking for expl... no
checking for fmaf... no
checking for fma... no
checking for fmal... no
checking for frexpf... no
checking for frexpl... no
checking for logl... no
checking for log10l... no
checking for clog10f... no
checking for clog10... no
checking for clog10l... no
checking for nextafterf... no
checking for nextafter... no
checking for nextafterl... no
checking for lroundl... no
checking for llroundf... no
checking for llround... no
checking for llroundl... no
checking for sinl... no
checking for sinhl... no
checking for tanl... no
checking for tanhl... no
checking for erfcl... no
checking for j0f... no
checking for j1f... no
checking for jnf... no
checking for jnl... no
checking for y0f... no
checking for y1f... no
checking for ynf... no
checking for ynl... no
checking for tgamma... no
checking for tgammaf... no
checking for lgammaf... no

Except for the Bessel functions these are a part of ISO C; `long double' 
versions, some of which appear missing unlike their `float' or `double' 
counterparts, should probably just alias to the corresponding `double' 
versions as I doubt we want to get into the H-floating format, largely 
missing from actual VAX hardware and meant to be emulated by the OS.

 Please note that this is with NetBSD 9 rather than 9.1 (which has only 
been recently released and therefore I decided not to get distracted with 
an upgrade) and I don't know if it has been fixed in the latter release.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-12-08 14:38                     ` Maciej W. Rozycki
@ 2020-12-08 15:22                       ` Martin Husemann
  0 siblings, 0 replies; 117+ messages in thread
From: Martin Husemann @ 2020-12-08 15:22 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Tobias Burnus, Joseph Myers, Thomas Koenig, Anders Magnusson,
	gcc-patches, fortran

On Tue, Dec 08, 2020 at 02:38:59PM +0000, Maciej W. Rozycki wrote:
>  Here's the full list of math functions that the `configure' script in 
> libgfortran reports as missing:
> 
> checking for acosl... no
> checking for acoshf... no
[..]
> Except for the Bessel functions these are a part of ISO C; `long double' 
> versions, some of which appear missing unlike their `float' or `double' 
> counterparts, should probably just alias to the corresponding `double' 
> versions as I doubt we want to get into the H-floating format, largely 
> missing from actual VAX hardware and meant to be emulated by the OS.

Thanks for the list - I'll add the aliases soonish (they are likely already
there for the IEEE versions but missing from the vax code) and check
what remains missing then.

Martin

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-11-28 18:48     ` Paul Koning
@ 2020-12-09 14:06       ` Maciej W. Rozycki
  2020-12-10  1:33         ` Paul Koning
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-09 14:06 UTC (permalink / raw)
  To: Paul Koning; +Cc: GCC Patches

On Sat, 28 Nov 2020, Paul Koning wrote:

> > Hmm, I gather those systems are able to run some kind of BSD Unix: don't 
> > they support the r-commands which would allow you to run DejaGNU testing 
> > with a realistic environment PDP-11 hardware would be usually used with, 
> > possibly on actual hardware even?  I always feel a bit uneasy about the 
> > accuracy of any simulation (having suffered from bugs in QEMU causing 
> > false negatives in software verification).
> 
> Fair enough.  But SIMH is a full system emulator with a very large 
> amount of history and expertise involved in its creation.  It's also 
> known to run every PDP-11 OS and most diagnostics.  Yes, it certainly 
> runs BSD 2.x; the reason I didn't use that approach is that I don't know 
> it well.

 This all sounds great.  Do you happen to know if it is cycle-accurate 
with respect to individual hardware microarchitectures simulated?  That 
would be required for performance evaluation of compiler-generated code.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation
  2020-11-20  3:36 ` [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation Maciej W. Rozycki
  2020-11-22  3:27   ` Jeff Law
@ 2020-12-09 16:09   ` Maciej W. Rozycki
  1 sibling, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-09 16:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, Anders Magnusson, Paul Koning, Matt Thomas

On Fri, 20 Nov 2020, Maciej W. Rozycki wrote:

> Outliers:
> 
> old     new     change  %change filename
> ----------------------------------------------------
> 2406    2950    +544    +22.610 20111208-1.exe
> 4314    5329    +1015   +23.528 pr39417.exe
> 2235    3055    +820    +36.689 990404-1.exe
> 2631    4213    +1582   +60.129 pr57521.exe
> 3063    5579    +2516   +82.142 20000422-1.exe

 So as a matter of interest I have actually looked into the worst offender 
shown above.  As I have just learnt by chance, GNU `size' in its default 
BSD mode reports code combined with rodata as text, so I have rerun it in 
the recently introduced GNU mode with `20000422-1.exe' and the results are 
worse yet:

       text       data        bss      total filename
-      1985       1466         68       3519 ./20000422-1.exe
+      4501       1466         68       6035 ./20000422-1.exe

However upon actual inspection code produced looks sound and it's just 
that the loops the test case has get unrolled further.  With speed 
optimisation this is not necessarily bad.  Mind that the options used for 
this particular compilation are `-O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions' meaning that, well, ahem, we do 
want loops to get unrolled and we want speed rather than size.  So all is 
well.

 I have tried to run some benchmarking with this test case, by putting all 
the files involved in tmpfs (i.e. RAM) so as to limit any I/O influence 
and looping the executable 1000 times, which yielded elapsed times of 
around 340s, i.e. with a good resolution, but results are inconclusive and 
the execution time oscillates on individual runs around the value shown, 
regardless of whether this change has been applied or not.

 So I have to conclude that either both variants of code are virtually 
equivalent in terms of performance or that the test environment keeps 
execution I/O-bound despite the measures I have taken.  Sadly the VAX 
architecture does not provide a user-accessible cycle count (I would know 
of) that could be used for more accurate measurements, and I do not feel 
right now like fiddling with the code of the test case any further so as 
to make it more suited for performance evaluation.

 I have to note however on this occasion that this part of the change:

-(define_insn "*cmp<mode>"
-  [(set (cc0)
-	(compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
-		 (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
+(define_insn "*cmp<VAXint:mode>_<VAXcc:mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+	(compare:VAXcc (match_operand:VAXint 0 "general_operand" "nrmT,nrmT")
+		       (match_operand:VAXint 1 "general_operand" "I,nrmT")))]

which allowed an immediate with operand #0 has improved code generation a 
little bit with this test case as well, because rather than this:

	clrl %r0
[...]
	cmpl %r0,%r1
[...]
	cmpl %r0,%r3
[...]

this:

	cmpl $0,%r1
[...]
	cmpl $0,%r3
[...]

is produced, which does not waste a register to hold the value of 0 which 
can be supplied in the literal addressing mode, i.e. with the operand 
specifier byte itself just like with register operands, and therefore does 
not require extra space or execution time.

 I don't know however why the middle end insists on supplying constant 0 
as operand #0 to the comparison operation (or the `cbranch4' insn it has 
originated from).  While we have machine support for such a comparison, 
having constant 0 supplied as operand #1 would permit the use of the TST 
instruction, one byte shorter.  Of course that would require reversing the 
condition of any branches using the output of the comparison, but unlike 
typical RISC ISAs the VAX ISA supports all the conditions as does our MD.

 Oddly enough making constant 0 more expensive in operand #0 than in 
operand #1 for comparison operations or COMPARE does not persuade the 
middle end to try and swap the operands, and making the `cbranch4' insns 
reject an immediate in operand #0 only makes reload put it back in a 
register.  All this despite COMPARE documentation saying:

    "If one of the operands is a constant, it should be placed in the
     second operand and the comparison code adjusted as appropriate."

So this looks like a missed optimisation and something to investigate at 
one point.

 Also, interestingly, we have this comment in our MD:

;; The VAX move instructions have space-time tradeoffs.  On a MicroVAX
;; register-register mov instructions take 3 bytes and 2 CPU cycles.  clrl
;; takes 2 bytes and 3 cycles.  mov from constant to register takes 2 cycles
;; if the constant is smaller than 4 bytes, 3 cycles for a longword
;; constant.  movz, mneg, and mcom are as fast as mov, so movzwl is faster
;; than movl for positive constants that fit in 16 bits but not 6 bits.  cvt
;; instructions take 4 cycles.  inc takes 3 cycles.  The machine description
;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
;; instead of movl).

which clearly states that the cost of a const 0 rtx varies depending on 
whether it is implied as with the CLR instruction or explicitly encoded as 
with MOV.  This must surely be true for the MicroVAX microarchitecture 
referred.  Which I gather however must have been solely microcoded unlike 
at least some later implementations such as the NVAX, which used a mixed 
pipeline/microcode microarchitecture familiar to many from modern x86 
processors.  I doubt with such an implementation an implicit 0 operand 
would require an extra machine clock for execution.  Which means we'd 
better review the costs at some point and make them model-specific.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-12-09 14:06       ` Maciej W. Rozycki
@ 2020-12-10  1:33         ` Paul Koning
  2020-12-11 14:54           ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Paul Koning @ 2020-12-10  1:33 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: GCC Patches



> On Dec 9, 2020, at 9:06 AM, Maciej W. Rozycki <macro@linux-mips.org> wrote:
> 
> On Sat, 28 Nov 2020, Paul Koning wrote:
> 
>>> Hmm, I gather those systems are able to run some kind of BSD Unix: don't 
>>> they support the r-commands which would allow you to run DejaGNU testing 
>>> with a realistic environment PDP-11 hardware would be usually used with, 
>>> possibly on actual hardware even?  I always feel a bit uneasy about the 
>>> accuracy of any simulation (having suffered from bugs in QEMU causing 
>>> false negatives in software verification).
>> 
>> Fair enough.  But SIMH is a full system emulator with a very large 
>> amount of history and expertise involved in its creation.  It's also 
>> known to run every PDP-11 OS and most diagnostics.  Yes, it certainly 
>> runs BSD 2.x; the reason I didn't use that approach is that I don't know 
>> it well.
> 
> This all sounds great.  Do you happen to know if it is cycle-accurate 
> with respect to individual hardware microarchitectures simulated?  That 
> would be required for performance evaluation of compiler-generated code.

No, it isn't.  I believe it just charges one time unit per instruction, with the possible exception of CIS instructions. 

I don't know of any cycle accurate PDP-11 emulators.  It's not even clear if it is possible to build one, given the asynchronous operation of the UNIBUS.  It certainly would be extremely difficult since even the documented timing is amazingly complex, never mind the possibility that the reality is different from what is documented.

The pdp11 back end uses a very rough approximation of the documented 11/70 timing, but GCC doesn't make it easy (or maybe not even possible) to use the full timing details.  It's not something I'd expect to refine a whole lot further.

More interesting would be to tweak the optimizing machinery to improve parts that either have bitrotted or never actually worked. The code generation for auto-increment etc. isn't particularly effective and I think that's a known limitation.  Ditto indirect addressing, since few other machines have that.  (VAX does, of course; it might benefit too.)  And with LRA things are more limited still, again this seems to be known and is caused by the focus on modern machine architectures.

	paul


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-12-10  1:33         ` Paul Koning
@ 2020-12-11 14:54           ` Maciej W. Rozycki
  2020-12-11 21:50             ` Paul Koning
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-11 14:54 UTC (permalink / raw)
  To: Paul Koning; +Cc: GCC Patches

On Wed, 9 Dec 2020, Paul Koning wrote:

> > This all sounds great.  Do you happen to know if it is cycle-accurate 
> > with respect to individual hardware microarchitectures simulated?  That 
> > would be required for performance evaluation of compiler-generated code.
> 
> No, it isn't.  I believe it just charges one time unit per instruction, 
> with the possible exception of CIS instructions.

 Fair enough, from experience most CPU emulators are instruction-accurate 
only.  Of all the generally available emulators I came across (and looked 
into closely enough; maybe I missed something) only ones for the Z80 were 
cycle-accurate, and I believe the MAME project has had cycle-accurate 
emulation, both down to the system level and both out of necessity, as 
software they were written for was often unforgiving when it comes to any 
discrepancy with respect to original hardware.

 Commercially, MIPS Technologies used to have cycle-accurate MIPSsim, 
actually used for hardware verification, and taking into account all the 
implementation details such as the TLB and caches of individual CPU cores 
supported.  And you could choose the topology of these resources according 
to what actual silicon could have.  Some LV hardware has had it too for 
evaluation purposes:

YAMON> scpu
Current settings :
  I-Cache bytes per way = 0x1000
  I-Cache associativity = 4
  D-Cache bytes per way = 0x1000
  D-Cache associativity = 4
  MMU                   = tlb
YAMON> scpu -a
Available settings :
  I-Cache bytes per way : 0x1000, 0x0
  I-Cache associativity : 4, 3, 2, 1
  D-Cache bytes per way : 0x1000, 0x0
  D-Cache associativity : 4, 3, 2, 1
  MMU types             : tlb, fixed
YAMON> scpu -i 0x1000 2
YAMON> scpu -d 0x1000 2
YAMON> scpu fixed
YAMON> scpu
Current settings :
  I-Cache bytes per way = 0x1000
  I-Cache associativity = 2
  D-Cache bytes per way = 0x1000
  D-Cache associativity = 2
  MMU                   = fixed
YAMON> 

But then even cycle-accurate MIPSsim would not take every parameter of a 
system into account, such as the latency of peripheral components.  Not 
sure about DRAM either, though being predictable I guess that might have 
been simulated.

> I don't know of any cycle accurate PDP-11 emulators.  It's not even 
> clear if it is possible to build one, given the asynchronous operation 
> of the UNIBUS.  It certainly would be extremely difficult since even the 
> documented timing is amazingly complex, never mind the possibility that 
> the reality is different from what is documented.

 For the purpose of compiler's performance evaluation however I don't 
think we need to go down as far as the external bus, so however UNIBUS 
performs should not really matter.  Even with the modern systems all the 
pipeline descriptions and operation timings we have recorded within GCC 
reflect perfect operating conditions such as hot caches, no TLB misses, no 
branch mispredictions, to say nothing of disruption to all that caused by 
hardware interrupts and context switches.

 So I guess with cycle-accurate PDP-11 emulation it would be sufficient if 
relative CPU instruction execution timings were correctly reflected, such 
as the latency of say MOV vs DIV, as I am fairly sure they are not even 
close to being equivalent.  But that does come at a cost; cycle-accurate 
MIPSsim was much slower than its instruction-accurate counterpart which 
also existed.

> The pdp11 back end uses a very rough approximation of the documented 
> 11/70 timing, but GCC doesn't make it easy (or maybe not even possible) 
> to use the full timing details.  It's not something I'd expect to refine 
> a whole lot further.

 Understood.

> More interesting would be to tweak the optimizing machinery to improve 
> parts that either have bitrotted or never actually worked. The code 
> generation for auto-increment etc. isn't particularly effective and I 
> think that's a known limitation.  Ditto indirect addressing, since few 
> other machines have that.  (VAX does, of course; it might benefit too.)  
> And with LRA things are more limited still, again this seems to be known 
> and is caused by the focus on modern machine architectures.

 Correctness absolutely has to take precedence over performance, but that 
does not mean the latter has to be completely ignored either.  And the 
presence of tools may only help with that.  We may not have the resources 
available commercially significant ports have, but that does not mean we 
should decide upfront to abandon any kind of performance QA.  I think we 
can still act professionally and try to do our best to make the quality of 
code produced as good as possible within our available resources.

 FWIW,

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included)
  2020-12-11 14:54           ` Maciej W. Rozycki
@ 2020-12-11 21:50             ` Paul Koning
  0 siblings, 0 replies; 117+ messages in thread
From: Paul Koning @ 2020-12-11 21:50 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: GCC Patches



> On Dec 11, 2020, at 9:54 AM, Maciej W. Rozycki <macro@linux-mips.org> wrote:
> 
> On Wed, 9 Dec 2020, Paul Koning wrote:
> 
>>> This all sounds great.  Do you happen to know if it is cycle-accurate 
>>> with respect to individual hardware microarchitectures simulated?  That 
>>> would be required for performance evaluation of compiler-generated code.
>> 
>> No, it isn't.  I believe it just charges one time unit per instruction, 
>> with the possible exception of CIS instructions.
> 
> Fair enough, from experience most CPU emulators are instruction-accurate 
> only.  Of all the generally available emulators I came across (and looked 
> into closely enough; maybe I missed something) only ones for the Z80 were 
> cycle-accurate, and I believe the MAME project has had cycle-accurate 
> emulation, both down to the system level and both out of necessity, as 
> software they were written for was often unforgiving when it comes to any 
> discrepancy with respect to original hardware.

I know of a cycle-accurate CDC 6000 simulator, but I think that was a one man project never released.

> Commercially, MIPS Technologies used to have cycle-accurate MIPSsim, 
> actually used for hardware verification, and taking into account all the 
> implementation details such as the TLB and caches of individual CPU cores 
> supported.

There was also a simulator with capabilities like that for the SB-1 CPU core of the Sibyte SB-1250 SoC. 

> ...
>> I don't know of any cycle accurate PDP-11 emulators.  It's not even 
>> clear if it is possible to build one, given the asynchronous operation 
>> of the UNIBUS.  It certainly would be extremely difficult since even the 
>> documented timing is amazingly complex, never mind the possibility that 
>> the reality is different from what is documented.
> 
> For the purpose of compiler's performance evaluation however I don't 
> think we need to go down as far as the external bus, so however UNIBUS 
> performs should not really matter.  Even with the modern systems all the 
> pipeline descriptions and operation timings we have recorded within GCC 
> reflect perfect operating conditions such as hot caches, no TLB misses, no 
> branch mispredictions, to say nothing of disruption to all that caused by 
> hardware interrupts and context switches.

True, but I was thinking of models where the UNIBUS is used for memory.  The real issue is that the documented timings are full of strange numbers.  There isn't a timing for a given instruction, but rather a whole pile of numbers depending on the addressing modes, with occasional exceptions to a pattern (for example, some register to register operations are faster than the general pattern for the operation and addressing mode costs would suggest).  And it's hard to find a number that can be used as the "cycle time" where each time value is a small multiple of that basic number.  That's an issue both for a timing simulation and also for the GCC instruction scheduler and instruction cost models -- I ended up rounding things rather drastically and trimming out some detail in order to have the cost values be small integers and not blow up the size of the scheduler state machine.

> So I guess with cycle-accurate PDP-11 emulation it would be sufficient if 
> relative CPU instruction execution timings were correctly reflected, such 
> as the latency of say MOV vs DIV, as I am fairly sure they are not even 
> close to being equivalent.  But that does come at a cost; cycle-accurate 
> MIPSsim was much slower than its instruction-accurate counterpart which 
> also existed.
> 
> ...
>> More interesting would be to tweak the optimizing machinery to improve 
>> parts that either have bitrotted or never actually worked. The code 
>> generation for auto-increment etc. isn't particularly effective and I 
>> think that's a known limitation.  Ditto indirect addressing, since few 
>> other machines have that.  (VAX does, of course; it might benefit too.)  
>> And with LRA things are more limited still, again this seems to be known 
>> and is caused by the focus on modern machine architectures.
> 
> Correctness absolutely has to take precedence over performance, but that 
> does not mean the latter has to be completely ignored either.  And the 
> presence of tools may only help with that.  We may not have the resources 
> available commercially significant ports have, but that does not mean we 
> should decide upfront to abandon any kind of performance QA.  I think we 
> can still act professionally and try to do our best to make the quality of 
> code produced as good as possible within our available resources.

Definitely.  For me, one complication is that the key bits of the common code are things I don't really understand and there isn't much documentation, especially for the LRA case.  Some of what is documented apparently hasn't been correct in many years, and possibly was never correct.  I think some of the auto-increment facilities fall in that category.

	paul


^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-11-20  3:36 ` [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant Maciej W. Rozycki
  2020-11-21  4:07   ` Jeff Law
@ 2020-12-15  8:26   ` Martin Liška
  2020-12-15 14:06     ` Maciej W. Rozycki
  1 sibling, 1 reply; 117+ messages in thread
From: Martin Liška @ 2020-12-15  8:26 UTC (permalink / raw)
  To: Maciej W. Rozycki, gcc-patches; +Cc: Anders Magnusson

On 11/20/20 4:36 AM, Maciej W. Rozycki wrote:
> We do not define a comparison operation between floating-point and
> integer data, including integer zero constant.  Consequently the RTL
> instruction stream presented to the post-reload comparison elimination
> pass will include, where applicable, floating-point comparison insns
> against `const_double:DF 0.0 [0x0.0p+0]' rather than `const_int 0 [0]',
> meaning that the latter expression will not match when used in machine
> description.
> 
> Use `const_double_zero' then for the relevant patterns to match the
> intended RTL instructions.
> 
> 	gcc/
> 	* config/pdp11/pdp11.md (fcc_cc, fcc_ccnz): Use
> 	`const_double_zero' to express double zero constant.
> ---
>   gcc/config/pdp11/pdp11.md | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md
> index 7a4d50fdba9..cdef49f3979 100644
> --- a/gcc/config/pdp11/pdp11.md
> +++ b/gcc/config/pdp11/pdp11.md
> @@ -105,7 +105,7 @@ (define_subst "fcc_cc"
>      (clobber (reg FCC_REGNUM))]
>     ""
>     [(set (reg:CC FCC_REGNUM)
> -	(compare:CC (match_dup 1) (const_int 0)))
> +	(compare:CC (match_dup 1) (const_double_zero)))
>      (set (match_dup 0) (match_dup 1))])
>   
>   (define_subst "fcc_ccnz"
> @@ -113,7 +113,7 @@ (define_subst "fcc_ccnz"
>      (clobber (reg FCC_REGNUM))]
>     ""
>     [(set (reg:CCNZ FCC_REGNUM)
> -	(compare:CCNZ (match_dup 1) (const_int 0)))
> +	(compare:CCNZ (match_dup 1) (const_double_zero)))
>      (set (match_dup 0) (match_dup 1))])
>   
>   (define_subst_attr "cc_cc" "cc_cc" "_nocc" "_cc")
> 

Hello.

If I see correctly, starting from this revision I can't compile a cross
compiler of x86_64-linux-gnu:

../configure --target=pdp11-aout --disable-bootstrap --enable-languages=c,c++ --disable-multilib  --enable-obsolete

$ make
build/genemit ../../gcc/common.md ../../gcc/config/pdp11/pdp11.md \
   insn-conditions.md > tmp-emit.c
genemit: Internal error: abort in gen_exp, at genemit.c:202
make: *** [Makefile:2427: s-emit] Error 1

$ Breakpoint 1, fancy_abort (file=0x435238 "../../gcc/genemit.c", line=202, func=0x435230 "gen_exp") at ../../gcc/errors.c:133
133	  internal_error ("abort in %s, at %s:%d", func, trim_filename (file), line);
(gdb) bt
#0  fancy_abort (file=0x435238 "../../gcc/genemit.c", line=202, func=0x435230 "gen_exp") at ../../gcc/errors.c:133
#1  0x0000000000402e4b in gen_exp (x=0x470de0, subroutine_type=DEFINE_INSN, used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:202
#2  0x0000000000402f68 in gen_exp (x=0x4d6c70, subroutine_type=DEFINE_INSN, used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:227
#3  0x0000000000402f68 in gen_exp (x=0x4d6c50, subroutine_type=DEFINE_INSN, used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:227
#4  0x000000000040307d in gen_exp (x=0x4aa490, subroutine_type=DEFINE_INSN, used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:255
#5  0x00000000004036c1 in gen_insn (info=0x7fffffffdea0) at ../../gcc/genemit.c:435
#6  0x0000000000404930 in main (argc=3, argv=0x7fffffffdfc8) at ../../gcc/genemit.c:911

Can you please take a look?
Thanks,
Martin

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-12-15  8:26   ` Martin Liška
@ 2020-12-15 14:06     ` Maciej W. Rozycki
  2020-12-15 18:02       ` Paul Koning
  0 siblings, 1 reply; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-15 14:06 UTC (permalink / raw)
  To: Martin Liška, Paul Koning; +Cc: gcc-patches

On Tue, 15 Dec 2020, Martin Liška wrote:

> If I see correctly, starting from this revision I can't compile a cross
> compiler of x86_64-linux-gnu:
> 
> ../configure --target=pdp11-aout --disable-bootstrap --enable-languages=c,c++
> --disable-multilib  --enable-obsolete

 Thanks for the heads-up and the details of the configuration, and sorry 
for the breakage.

> $ make
> build/genemit ../../gcc/common.md ../../gcc/config/pdp11/pdp11.md \
>   insn-conditions.md > tmp-emit.c
> genemit: Internal error: abort in gen_exp, at genemit.c:202
> make: *** [Makefile:2427: s-emit] Error 1
> 
> $ Breakpoint 1, fancy_abort (file=0x435238 "../../gcc/genemit.c", line=202,
> func=0x435230 "gen_exp") at ../../gcc/errors.c:133
> 133	  internal_error ("abort in %s, at %s:%d", func, trim_filename (file),
> line);
> (gdb) bt
> #0  fancy_abort (file=0x435238 "../../gcc/genemit.c", line=202, func=0x435230
> "gen_exp") at ../../gcc/errors.c:133
> #1  0x0000000000402e4b in gen_exp (x=0x470de0, subroutine_type=DEFINE_INSN,
> used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:202
> #2  0x0000000000402f68 in gen_exp (x=0x4d6c70, subroutine_type=DEFINE_INSN,
> used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:227
> #3  0x0000000000402f68 in gen_exp (x=0x4d6c50, subroutine_type=DEFINE_INSN,
> used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:227
> #4  0x000000000040307d in gen_exp (x=0x4aa490, subroutine_type=DEFINE_INSN,
> used=0x4aa4b0 "", info=0x7fffffffdea0) at ../../gcc/genemit.c:255
> #5  0x00000000004036c1 in gen_insn (info=0x7fffffffdea0) at
> ../../gcc/genemit.c:435
> #6  0x0000000000404930 in main (argc=3, argv=0x7fffffffdfc8) at
> ../../gcc/genemit.c:911

 I don't have the target environment available and consequently the target 
does not complete building for me:

The directory that should contain system headers does not exist:
  .../usr/sysroot/usr/include
make[2]: *** [Makefile:3218: stmp-fixinc] Error 1

or otherwise I would have at least tried to compile it before submitting 
the change.  The configuration does build far enough to trigger this issue 
though and I can confirm the change is indeed the culprit.

> Can you please take a look?

 I'm fairly sure this is due to the difference in TARGET_SUPPORTS_WIDE_INT
with the VAX backend vs the PDP-11 one.  I have an idea how this should be 
addressed and will be implementing it shortly.

 NB the backend fails `-Werror' compilation:

In file included from ./tm.h:18,
                 from .../gcc/backend.h:28,
                 from .../gcc/varasm.c:31:
.../gcc/varasm.c: In function 'void assemble_zeros(long unsigned int)':
.../gcc/config/pdp11/pdp11.h:622:20: error: format '%o' expects argument of type 'unsigned int', but argument 3 has type 'long unsigned int' [-Werror=format=]
  622 |     fprintf (FILE, "\t.blkb\t%o\n", (SIZE) & 0xffff);   \
      |                    ^~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~
      |                                            |
      |                                            long unsigned int

etc., so that has to be disabled.  This may be with 64-bit hosts only, I'm 
not sure, however the way varargs are handled means the issue will likely 
cause a broken compiler to be built if the warning is ignored, at least 
with some hosts.

 Paul, can you please look into it sometime?

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-12-15 14:06     ` Maciej W. Rozycki
@ 2020-12-15 18:02       ` Paul Koning
  2020-12-15 18:38         ` Maciej W. Rozycki
  0 siblings, 1 reply; 117+ messages in thread
From: Paul Koning @ 2020-12-15 18:02 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Martin Liška, GCC Patches



> On Dec 15, 2020, at 9:06 AM, Maciej W. Rozycki <macro@linux-mips.org> wrote:
> 
> On Tue, 15 Dec 2020, Martin Liška wrote:
> 
>> If I see correctly, starting from this revision I can't compile a cross
>> compiler of x86_64-linux-gnu:
>> 
>> ../configure --target=pdp11-aout --disable-bootstrap --enable-languages=c,c++
>> --disable-multilib  --enable-obsolete

PDP11 doesn't do C++, there isn't any way to do that with aout that I have seen (no named section support).  There's been some experimental work on ELF for pdp11 (!) which should make this possible but I haven't tried that yet.

> 
> Thanks for the heads-up and the details of the configuration, and sorry 
> for the breakage.
> ...
> 
>> Can you please take a look?
> 
> I'm fairly sure this is due to the difference in TARGET_SUPPORTS_WIDE_INT
> with the VAX backend vs the PDP-11 one.  I have an idea how this should be 
> addressed and will be implementing it shortly.

What's the difference?  pdp11 does support wide int.

> NB the backend fails `-Werror' compilation:
> 
> In file included from ./tm.h:18,
>                 from .../gcc/backend.h:28,
>                 from .../gcc/varasm.c:31:
> .../gcc/varasm.c: In function 'void assemble_zeros(long unsigned int)':
> .../gcc/config/pdp11/pdp11.h:622:20: error: format '%o' expects argument of type 'unsigned int', but argument 3 has type 'long unsigned int' [-Werror=format=]
>  622 |     fprintf (FILE, "\t.blkb\t%o\n", (SIZE) & 0xffff);   \
>      |                    ^~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~
>      |                                            |
>      |                                            long unsigned int
> 
> etc., so that has to be disabled.  This may be with 64-bit hosts only, I'm 
> not sure, however the way varargs are handled means the issue will likely 
> cause a broken compiler to be built if the warning is ignored, at least 
> with some hosts.
> 
> Paul, can you please look into it sometime?

Will do, thanks.

	paul



^ permalink raw reply	[flat|nested] 117+ messages in thread

* Re: [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant
  2020-12-15 18:02       ` Paul Koning
@ 2020-12-15 18:38         ` Maciej W. Rozycki
  0 siblings, 0 replies; 117+ messages in thread
From: Maciej W. Rozycki @ 2020-12-15 18:38 UTC (permalink / raw)
  To: Paul Koning; +Cc: Martin Liška, GCC Patches

On Tue, 15 Dec 2020, Paul Koning wrote:

> > I'm fairly sure this is due to the difference in TARGET_SUPPORTS_WIDE_INT
> > with the VAX backend vs the PDP-11 one.  I have an idea how this should be 
> > addressed and will be implementing it shortly.
> 
> What's the difference?  pdp11 does support wide int.

 The VAX backend, being old-fashioned, does not and therefore overloads 
the CONST_DOUBLE rtx for that purpose, making it possibly relevant here 
(it has turned out not after all: the cause is the use of named patterns 
for the CC-setting insns referred to by splitters, which the VAX backend 
does not have).  NB there's been no rush to update the VAX backend for 
proper wide integer support, which will require some caution AFAICT.

 Anyway I have a fix now I am satisfied with and will be posting it 
shortly.  I'll appreciate it if you verify it as I have no means beyond 
making sure that it builds.  I'll cc you on the upcoming submission; a 
general maintainer will have to approve it though.

  Maciej

^ permalink raw reply	[flat|nested] 117+ messages in thread

end of thread, other threads:[~2020-12-15 18:38 UTC | newest]

Thread overview: 117+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20  3:38 [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Maciej W. Rozycki
2020-11-20  3:34 ` [PATCH 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address Maciej W. Rozycki
2020-11-20 10:55   ` Eric Botcazou
2020-11-20 15:30     ` Maciej W. Rozycki
2020-11-24  6:19       ` [PATCH v2 " Maciej W. Rozycki
2020-11-24 11:03         ` Eric Botcazou
2020-11-26 17:22           ` Maciej W. Rozycki
2020-11-27  3:51             ` Maciej W. Rozycki
2020-11-27 10:52         ` Ulrich Weigand
2020-11-27 19:22           ` Maciej W. Rozycki
2020-11-27 20:47             ` Maciej W. Rozycki
2020-11-27 20:50               ` [PATCH v3 " Maciej W. Rozycki
2020-11-30 18:51                 ` Jeff Law
2020-11-29 17:31             ` [PATCH v2 " Jeff Law
2020-11-20  3:34 ` [PATCH 02/31] VAX: Remove `c' operand format specifier overload Maciej W. Rozycki
2020-11-20 23:16   ` Jeff Law
2020-11-24  1:12   ` Segher Boessenkool
2020-11-20  3:34 ` [PATCH 03/31] VAX: Define LEGITIMATE_PIC_OPERAND_P Maciej W. Rozycki
2020-11-21  3:17   ` Jeff Law
2020-11-20  3:34 ` [PATCH 04/31] VAX/testsuite: Run target testing over all the usual optimization levels Maciej W. Rozycki
2020-11-20 23:17   ` Jeff Law
2020-11-20  3:34 ` [PATCH 05/31] VAX: Rationalize expression and address costs Maciej W. Rozycki
2020-11-21  3:48   ` Jeff Law
2020-11-20  3:34 ` [PATCH 06/31] VAX: Correct fatal issues with the `ffs' builtin Maciej W. Rozycki
2020-11-20 23:19   ` Jeff Law
2020-11-20  3:34 ` [PATCH 07/31] RTL: Also support HOST_WIDE_INT with int iterators Maciej W. Rozycki
2020-11-21  4:19   ` Jeff Law
2020-11-20  3:34 ` [PATCH 08/31] jump: Also handle jumps wrapped in UNSPEC or UNSPEC_VOLATILE Maciej W. Rozycki
2020-11-21  4:25   ` Jeff Law
2020-12-03  3:50     ` [PATCH v2 " Maciej W. Rozycki
2020-12-03 22:20       ` Jeff Law
2020-11-20  3:34 ` [PATCH 09/31] VAX: Use a mode iterator to produce individual interlocked branches Maciej W. Rozycki
2020-11-20 23:20   ` Jeff Law
2020-11-20  3:34 ` [PATCH 10/31] VAX: Use an int " Maciej W. Rozycki
2020-11-20 23:20   ` Jeff Law
2020-11-20  3:35 ` [PATCH 11/31] VAX: Correct `sync_lock_test_and_set' and `sync_lock_release' builtins Maciej W. Rozycki
2020-11-21  4:26   ` Jeff Law
2020-11-20  3:35 ` [PATCH 12/31] VAX: Actually enable `builtins.md' now that it is fully functional Maciej W. Rozycki
2020-11-20 23:21   ` Jeff Law
2020-11-20  3:35 ` [PATCH 13/31] VAX: Add a test for the SImode `ffs' operation Maciej W. Rozycki
2020-11-20 23:22   ` Jeff Law
2020-11-20  3:35 ` [PATCH 14/31] VAX: Add tests for `sync_lock_test_and_set' and `sync_lock_release' Maciej W. Rozycki
2020-11-20 23:22   ` Jeff Law
2020-11-20  3:35 ` [PATCH 15/31] VAX: Provide the `ctz' operation Maciej W. Rozycki
2020-11-20 23:23   ` Jeff Law
2020-11-20  3:35 ` [PATCH 16/31] VAX: Also provide QImode and HImode `ctz' and `ffs' operations Maciej W. Rozycki
2020-11-20 23:24   ` Jeff Law
2020-11-20  3:35 ` [PATCH 17/31] VAX: Actually produce QImode and HImode `ctz' operations Maciej W. Rozycki
2020-11-20 23:24   ` Jeff Law
2020-11-20  3:35 ` [PATCH 18/31] VAX: Add a test for the `cpymemhi' instruction Maciej W. Rozycki
2020-11-20 23:25   ` Jeff Law
2020-11-20  3:35 ` [PATCH 19/31] VAX: Add the `movmemhi' instruction Maciej W. Rozycki
2020-11-20 23:25   ` Jeff Law
2020-11-20  3:35 ` [PATCH 20/31] VAX: Fix predicates and constraints for EXTV/EXTZV/INSV insns Maciej W. Rozycki
2020-11-21 17:01   ` Jeff Law
2020-11-20  3:35 ` [PATCH 21/31] VAX: Remove EXTV/EXTZV/INSV instruction use from aligned case insns Maciej W. Rozycki
2020-11-21 17:25   ` Jeff Law
2020-11-20  3:35 ` [PATCH 22/31] VAX: Ensure PIC mode address is adjustable with aligned bitfield insns Maciej W. Rozycki
2020-11-21 17:03   ` Jeff Law
2020-11-20  3:36 ` [PATCH 23/31] VAX: Make `extv' an expander matching the remaining bitfield operations Maciej W. Rozycki
2020-11-21 17:26   ` Jeff Law
2020-11-20  3:36 ` [PATCH 24/31] VAX: Fix predicates and constraints for bitfield comparison insns Maciej W. Rozycki
2020-11-21 17:27   ` Jeff Law
2020-11-20  3:36 ` [PATCH 25/31] VAX: Fix predicates for widening multiply and multiply-add insns Maciej W. Rozycki
2020-11-21  4:05   ` Jeff Law
2020-11-30 16:02     ` Maciej W. Rozycki
2020-11-30 18:29       ` Jeff Law
2020-11-20  3:36 ` [PATCH 26/31] VAX: Correct issues with commented-out insns Maciej W. Rozycki
2020-11-21  4:05   ` Jeff Law
2020-11-20  3:36 ` [PATCH 27/31] VAX: Make the `divmoddisi4' and `*amulsi4' comment notation consistent Maciej W. Rozycki
2020-11-21  4:06   ` Jeff Law
2020-11-24  1:37   ` Segher Boessenkool
2020-11-20  3:36 ` [PATCH 28/31] RTL: Add `const_double_zero' syntactic rtx Maciej W. Rozycki
2020-11-21 17:29   ` Jeff Law
2020-11-20  3:36 ` [PATCH 29/31] PDP11: Use `const_double_zero' to express double zero constant Maciej W. Rozycki
2020-11-21  4:07   ` Jeff Law
2020-12-15  8:26   ` Martin Liška
2020-12-15 14:06     ` Maciej W. Rozycki
2020-12-15 18:02       ` Paul Koning
2020-12-15 18:38         ` Maciej W. Rozycki
2020-11-20  3:36 ` [PATCH 30/31] PR target/95294: VAX: Convert backend to MODE_CC representation Maciej W. Rozycki
2020-11-22  3:27   ` Jeff Law
2020-12-09 16:09   ` Maciej W. Rozycki
2020-11-20  3:37 ` [PATCH 31/31] PR target/95294: VAX: Add test cases for " Maciej W. Rozycki
2020-11-21  4:08   ` Jeff Law
2020-12-05 18:40     ` Maciej W. Rozycki
2020-11-20  7:58 ` [PATCH 00/31] VAX: Bring the port up to date (yes, MODE_CC conversion is included) Anders Magnusson
2020-11-23 20:31   ` Maciej W. Rozycki
2020-11-21 21:02 ` Toon Moene
2020-11-23 21:51   ` Maciej W. Rozycki
2020-11-23 22:12     ` Thomas Koenig
2020-11-24  4:28       ` Maciej W. Rozycki
2020-11-24  5:27         ` Maciej W. Rozycki
2020-11-24  6:04           ` Maciej W. Rozycki
2020-11-24  6:16             ` Thomas Koenig
2020-11-25 19:22               ` Maciej W. Rozycki
2020-11-25 18:26             ` Maciej W. Rozycki
2020-11-25 22:20               ` Joseph Myers
2020-11-26 18:01                 ` Maciej W. Rozycki
2020-11-26 18:08                   ` Martin Husemann
2020-12-08 14:38                     ` Maciej W. Rozycki
2020-12-08 15:22                       ` Martin Husemann
2020-11-25 22:26           ` coypu
2020-11-26 17:59             ` Maciej W. Rozycki
2020-11-26 19:35               ` Maciej W. Rozycki
2020-11-23 15:48 ` Paul Koning
2020-11-25 17:07   ` Maciej W. Rozycki
2020-11-28 18:48     ` Paul Koning
2020-12-09 14:06       ` Maciej W. Rozycki
2020-12-10  1:33         ` Paul Koning
2020-12-11 14:54           ` Maciej W. Rozycki
2020-12-11 21:50             ` Paul Koning
2020-11-25 18:36 ` Maciej W. Rozycki
2020-11-26 14:46   ` Ian Lance Taylor
2020-11-26 18:07     ` Maciej W. Rozycki
2020-11-29 17:56   ` Martin Sebor
2020-12-07 14:25     ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).