+2018-03-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/85044
+       * config/i386/i386.c (ix86_trampoline_init): Insert ENDBR for
+       -fcf-protection=branch -mibt.
+       * config/i386/i386.h (TRAMPOLINE_SIZE): Increased by 4 bytes.
+
 2018-03-27  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        PR target/81863
 
   rtx mem, fnaddr;
   int opcode;
   int offset = 0;
+  bool need_endbr = (flag_cf_protection & CF_BRANCH) && TARGET_IBT;
 
   fnaddr = XEXP (DECL_RTL (fndecl), 0);
 
     {
       int size;
 
+      if (need_endbr)
+       {
+         /* Insert ENDBR64.  */
+         mem = adjust_address (m_tramp, SImode, offset);
+         emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
+         offset += 4;
+       }
+
       /* Load the function address to r11.  Try to load address using
         the shorter movl instead of movabs.  We may want to support
         movq for kernel mode, but kernel does not use trampolines at
       else
        opcode = 0x68;
 
+      if (need_endbr)
+       {
+         /* Insert ENDBR32.  */
+         mem = adjust_address (m_tramp, SImode, offset);
+         emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
+         offset += 4;
+       }
+
       mem = adjust_address (m_tramp, QImode, offset);
       emit_move_insn (mem, gen_int_mode (opcode, QImode));
 
 
 
 /* Length in units of the trampoline for entering a nested function.  */
 
-#define TRAMPOLINE_SIZE (TARGET_64BIT ? 24 : 10)
+#define TRAMPOLINE_SIZE (TARGET_64BIT ? 28 : 14)
 \f
 /* Definitions for register eliminations.
 
 
--- /dev/null
+/* { dg-do run { target cet } } */
+/* { dg-options "-O2 -fcf-protection=branch -mibt" } */
+
+void callme (void (*callback) (void));
+
+int
+main (void)
+{
+  int ok = 0;
+  void callback (void) { ok = 1; }
+
+  callme (&callback);
+
+  if (!ok)
+   __builtin_abort ();
+  return 0;
+}
+
+__attribute__((noinline, noclone))
+void
+callme (void (*callback) (void))
+{
+  (*callback) ();
+}