diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv
index 75226d9345152a067895f1e8cbc0ca7eb374308b..d38908a636f44487628f921d32639696dc87f803 100644
--- a/src/frontend/frontend.sv
+++ b/src/frontend/frontend.sv
@@ -146,6 +146,7 @@ module frontend import ariane_pkg::*; #(
     logic [INSTR_PER_FETCH-1:0] is_jump;
     logic [INSTR_PER_FETCH-1:0] is_return;
     logic [INSTR_PER_FETCH-1:0] is_jalr;
+    logic [INSTR_PER_FETCH-1:0] is_cf;
 
     for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin
       // branch history table -> BHT
@@ -158,6 +159,9 @@ module frontend import ariane_pkg::*; #(
       assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]);
       // unconditional jumps with unknown target -> BTB
       assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & ~is_call[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
+
+      // cf that needs a prediction
+      assign is_cf[i] = instruction_valid[i] & (rvi_branch[i] | rvc_branch[i] | rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
     end
 
     // taken/not taken
@@ -423,6 +427,7 @@ module frontend import ariane_pkg::*; #(
       .flush_i             ( flush_i              ),
       .instr_i             ( instr                ), // from re-aligner
       .addr_i              ( addr                 ), // from re-aligner
+      .is_cf_i             ( is_cf                ),
       .exception_i         ( icache_ex_valid_q    ), // from I$
       .exception_addr_i    ( icache_vaddr_q       ),
       .predict_address_i   ( predict_address      ),
diff --git a/src/frontend/instr_queue.sv b/src/frontend/instr_queue.sv
index a31b096b995398fe8ee42f00933db9592f0581cc..51c612624865dd19ef3ae4201c6338f018fd0759 100644
--- a/src/frontend/instr_queue.sv
+++ b/src/frontend/instr_queue.sv
@@ -49,6 +49,7 @@ module instr_queue (
   input  logic                                               flush_i,
   input  logic [ariane_pkg::INSTR_PER_FETCH-1:0][31:0]       instr_i,
   input  logic [ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i,
+  input  logic [ariane_pkg::INSTR_PER_FETCH-1:0]             is_cf_i,
   input  logic [ariane_pkg::INSTR_PER_FETCH-1:0]             valid_i,
   output logic                                               ready_o,
   output logic [ariane_pkg::INSTR_PER_FETCH-1:0]             consumed_o,
@@ -73,6 +74,7 @@ module instr_queue (
   typedef struct packed {
     logic [31:0]     instr; // instruction word
     ariane_pkg::cf_t cf;    // branch was taken
+    logic            is_cf; // instruction is a cf that needs a prediction (ie. not a jump)
     ariane_pkg::frontend_exception_t ex;    // exception happened
     logic [riscv::VLEN-1:0] ex_vaddr;       // lower VLEN bits of tval for exception
   } instr_data_t;
@@ -127,7 +129,7 @@ module instr_queue (
   logic                                     output_is_mem;
 
   // cf count
-  logic [ariane_pkg::INSTR_PER_FETCH-1:0]  input_is_cf;
+  logic [ariane_pkg::INSTR_PER_FETCH*2-1:0]  input_is_cf;
   logic [ariane_pkg::INSTR_PER_FETCH-1:0] fifo_has_no_cf;
   logic                                   output_is_cf;
 
@@ -220,6 +222,8 @@ module instr_queue (
     assign instr[i + ariane_pkg::INSTR_PER_FETCH] = instr_i[i];
     assign cf[i] = cf_type_i[i];
     assign cf[i + ariane_pkg::INSTR_PER_FETCH] = cf_type_i[i];
+    assign input_is_cf[i] = is_cf_i[i];
+    assign input_is_cf[i + ariane_pkg::INSTR_PER_FETCH] = is_cf_i[i];
   end
 
   // shift the inputs
@@ -230,7 +234,7 @@ module instr_queue (
     assign instr_data_in[i].ex = exception_i; // exceptions hold for the whole fetch packet
     assign instr_data_in[i].ex_vaddr = exception_addr_i;
     assign input_is_mem_in[i] = input_is_mem[i + idx_is_q];
-    assign input_is_cf[i] = !(cf[i + idx_is_q] inside {ariane_pkg::NoCF, ariane_pkg::Jump});
+    assign instr_data_in[i].is_cf = input_is_cf[i + idx_is_q];
     /* verilator lint_on WIDTH */
   end
 
@@ -346,8 +350,6 @@ module instr_queue (
                                     (instr_data_out[i].instr[6:0] == riscv::OpcodeStoreFp) |
                                     (instr_data_out[i].instr[6:0] == riscv::OpcodeAmo));
 
-    assign fifo_output_is_cf[i] = !(instr_data_out[i].cf inside {ariane_pkg::NoCF, ariane_pkg::Jump});
-
     fifo_v3 #(
       .DEPTH ( ariane_pkg::FETCH_FIFO_DEPTH ),
       .dtype (logic)
@@ -377,9 +379,9 @@ module instr_queue (
       .empty_o (fifo_has_no_cf[i]),
       .usage_o (),
       .data_i (1'b1),
-      .push_i (push_instr_fifo[i] & !(instr_data_in[i].cf inside {ariane_pkg::NoCF, ariane_pkg::Jump})),
+      .push_i (push_instr_fifo[i] & instr_data_in[i].is_cf),
       .data_o (),
-      .pop_i (pop_instr[i] & fifo_output_is_cf[i])
+      .pop_i (pop_instr[i] & instr_data_out[i].is_cf)
     );
   end
   // or reduce and check whether we are retiring a taken branch (might be that the corresponding)