diff mbox series

[committed] i386: Rewrite restore_stack_nonlocal expander [PR96536].

Message ID CAFULd4bYzbGLgaU978frf-K+q62v++EJUWJROVYac8wVOXYHSw@mail.gmail.com
State New
Headers show
Series [committed] i386: Rewrite restore_stack_nonlocal expander [PR96536]. | expand

Commit Message

Uros Bizjak Aug. 18, 2020, 3:42 p.m. UTC
-fcf-protection code in restore_stack_nonlocal uses a branch based on
a clobber result.  The patch adds missing compare and completely
rewrites the expander to use high-level functions in RTL construction.

2020-08-18  Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog:

    PR target/96536
    * config/i386/i386.md (restore_stack_nonlocal): Add missing compare
    RTX.  Rewrite expander to use high-level functions in RTL construction.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Also
bootstrapped and regtested by Hongtao on CET enabled target (thanks).

Uros.

Comments

Uros Bizjak Aug. 18, 2020, 3:47 p.m. UTC | #1
On Tue, Aug 18, 2020 at 5:42 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> -fcf-protection code in restore_stack_nonlocal uses a branch based on
> a clobber result.  The patch adds missing compare and completely
> rewrites the expander to use high-level functions in RTL construction.

Backported gcc-10 version introduces only minimal change to the code.

2020-08-18  Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog:

    PR target/96536
    * config/i386/i386.md (restore_stack_nonlocal):
    Add missing compare RTX.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 292de142e90..44dbb79d008 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -18696,8 +18696,11 @@
       emit_insn (tmp);
 
       /* Compare and jump over adjustment code.  */
-      noadj_label = gen_label_rtx ();
+      tmp = gen_rtx_COMPARE (CCZmode, reg_ssp, const0_rtx);
       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
+      emit_insn (gen_rtx_SET (flags, tmp));
+
+      noadj_label = gen_label_rtx ();
       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
 				  gen_rtx_LABEL_REF (VOIDmode, noadj_label),
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3985c771d00..05af8639dbc 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -19133,15 +19133,17 @@ 
   ""
 {
   rtx stack_slot;
-  if ((flag_cf_protection & CF_RETURN))
+
+  if (flag_cf_protection & CF_RETURN)
     {
-      /* Copy shadow stack pointer to the first slot and stack ppointer
-	 to the second slot.  */
+      /* Copy shadow stack pointer to the first slot
+	 and stack pointer to the second slot.  */
       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
-      rtx ssp = force_reg (word_mode, const0_rtx);
-      emit_insn (gen_rdssp (word_mode, ssp, ssp));
-      emit_move_insn (ssp_slot, ssp);
+
+      rtx reg_ssp = force_reg (word_mode, const0_rtx);
+      emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
+      emit_move_insn (ssp_slot, reg_ssp);
     }
   else
     stack_slot = adjust_address (operands[0], Pmode, 0);
@@ -19155,95 +19157,64 @@ 
   ""
 {
   rtx stack_slot;
-  if ((flag_cf_protection & CF_RETURN))
+
+  if (flag_cf_protection & CF_RETURN)
     {
-      /* Restore shadow stack pointer from the first slot and stack
-	 pointer from the second slot.  */
+      /* Restore shadow stack pointer from the first slot
+	 and stack pointer from the second slot.  */
       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
 
-      rtx flags, jump, noadj_label, inc_label, loop_label;
-      rtx reg_adj, reg_ssp, tmp, clob;
-
       /* Get the current shadow stack pointer.  The code below will check if
 	 SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
 	 is a NOP.  */
-      reg_ssp = force_reg (word_mode, const0_rtx);
+      rtx reg_ssp = force_reg (word_mode, const0_rtx);
       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
 
-      /* Compare through substraction the saved and the current ssp to decide
-	 if ssp has to be adjusted.  */
-      tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
-						 ssp_slot));
-      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
-      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
-      emit_insn (tmp);
+      /* Compare through subtraction the saved and the current ssp
+	 to decide if ssp has to be adjusted.  */
+      reg_ssp = expand_simple_binop (word_mode, MINUS,
+				     reg_ssp, ssp_slot,
+				     reg_ssp, 1, OPTAB_DIRECT);
 
       /* Compare and jump over adjustment code.  */
-      noadj_label = gen_label_rtx ();
-      flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-      tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
-      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-				  gen_rtx_LABEL_REF (VOIDmode, noadj_label),
-				  pc_rtx);
-      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
-      JUMP_LABEL (jump) = noadj_label;
-
-      /* Compute the numebr of frames to adjust.  */
-      reg_adj = gen_lowpart (ptr_mode, reg_ssp);
-      tmp = gen_rtx_SET (reg_adj,
-			 gen_rtx_LSHIFTRT (ptr_mode,
-					   negate_rtx (ptr_mode, reg_adj),
-					   GEN_INT ((word_mode == SImode)
-						    ? 2
-						    : 3)));
-      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
-      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
-      emit_insn (tmp);
+      rtx noadj_label = gen_label_rtx ();
+      emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
+			       word_mode, 1, noadj_label);
 
-      /* Check if number of frames <= 255 so no loop is needed.  */
-      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
-      flags = gen_rtx_REG (CCmode, FLAGS_REG);
-      emit_insn (gen_rtx_SET (flags, tmp));
+      /* Compute the number of frames to adjust.  */
+      rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
+      rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
+					    NULL_RTX, 1);
 
-      inc_label = gen_label_rtx ();
-      tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
-      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-				  gen_rtx_LABEL_REF (VOIDmode, inc_label),
-				  pc_rtx);
-      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
-      JUMP_LABEL (jump) = inc_label;
+      reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
+				     GEN_INT (exact_log2 (UNITS_PER_WORD)),
+				     reg_adj, 1, OPTAB_DIRECT);
 
-      rtx reg_255 = gen_reg_rtx (word_mode);
-      emit_move_insn (reg_255, GEN_INT (255));
+      /* Check if number of frames <= 255 so no loop is needed.  */
+      rtx inc_label = gen_label_rtx ();
+      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
+			       ptr_mode, 1, inc_label);
 
       /* Adjust the ssp in a loop.  */
-      loop_label = gen_label_rtx ();
+      rtx loop_label = gen_label_rtx ();
       emit_label (loop_label);
       LABEL_NUSES (loop_label) = 1;
 
+      rtx reg_255 = force_reg (word_mode, GEN_INT (255));
       emit_insn (gen_incssp (word_mode, reg_255));
-      tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
-						 reg_adj,
-						 GEN_INT (255)));
-      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
-      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
-      emit_insn (tmp);
-
-      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
-      flags = gen_rtx_REG (CCmode, FLAGS_REG);
-      emit_insn (gen_rtx_SET (flags, tmp));
-
-      /* Jump to the loop label.  */
-      tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
-      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-				  gen_rtx_LABEL_REF (VOIDmode, loop_label),
-				  pc_rtx);
-      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
-      JUMP_LABEL (jump) = loop_label;
+
+      reg_adj = expand_simple_binop (ptr_mode, MINUS,
+				     reg_adj, GEN_INT (255),
+				     reg_adj, 1, OPTAB_DIRECT);
+
+      /* Compare and jump to the loop label.  */
+      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
+			       ptr_mode, 1, loop_label);
 
       emit_label (inc_label);
       LABEL_NUSES (inc_label) = 1;
+
       emit_insn (gen_incssp (word_mode, reg_ssp));
 
       emit_label (noadj_label);