LCOV - code coverage report
Current view: top level - gcc - crc-verification.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.1 % 491 408
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 35 35
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Execute symbolically all paths of the loop.
       2              :    Calculate the value of the polynomial by executing loop with real values to
       3              :    create LFSR state.
       4              :    After each iteration check that final states of calculated CRC values match
       5              :    determined LFSR.
       6              :    Copyright (C) 2022-2026 Free Software Foundation, Inc.
       7              :    Contributed by Mariam Arutunian <mariamarutunian@gmail.com>
       8              : 
       9              : This file is part of GCC.
      10              : 
      11              : GCC is free software; you can redistribute it and/or modify it under
      12              : the terms of the GNU General Public License as published by the Free
      13              : Software Foundation; either version 3, or (at your option) any later
      14              : version.
      15              : 
      16              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      17              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      18              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      19              : for more details.
      20              : 
      21              : You should have received a copy of the GNU General Public License
      22              : along with GCC; see the file COPYING3.  If not see
      23              : <http://www.gnu.org/licenses/>.   */
      24              : 
      25              : #include "crc-verification.h"
      26              : #include "config.h"
      27              : #include "system.h"
      28              : #include "coretypes.h"
      29              : #include "backend.h"
      30              : #include "tree.h"
      31              : #include "gimple.h"
      32              : #include "ssa.h"
      33              : #include "gimple-iterator.h"
      34              : #include "tree-cfg.h"
      35              : #include "cfganal.h"
      36              : #include "tree-ssa-loop.h"
      37              : 
      38              : /* Check whether defined variable is used outside the loop, only
      39              :    CRC's definition is allowed to be used outside the loop.  */
      40              : 
      41              : bool
      42        34949 : crc_symbolic_execution::is_used_outside_the_loop (tree def)
      43              : {
      44        34949 :   imm_use_iterator imm_iter;
      45        34949 :   gimple *use_stmt;
      46       110015 :   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
      47              :     {
      48        46430 :       if (!flow_bb_inside_loop_p (m_crc_loop, use_stmt->bb))
      49              :         {
      50         6313 :           if (is_a<gphi *> (use_stmt)
      51         6313 :               && as_a<gphi *> (use_stmt) == m_output_crc)
      52              :             return false;
      53            0 :           if (dump_file)
      54            0 :             fprintf (dump_file, "Defined variable is used outside the loop.\n");
      55            0 :           return true;
      56              :         }
      57         6313 :     }
      58        28636 :   return false;
      59              : }
      60              : 
      61              : /* Calculate value of the rhs operation of GS assignment statement
      62              :    and assign it to lhs variable.  */
      63              : 
      64              : bool
      65        30369 : crc_symbolic_execution::execute_assign_statement (const gassign *gs)
      66              : {
      67        30369 :   enum tree_code rhs_code = gimple_assign_rhs_code (gs);
      68        30369 :   tree lhs = gimple_assign_lhs (gs);
      69        30369 :   if (dump_file && (dump_flags & TDF_DETAILS))
      70        26367 :     fprintf (dump_file, "lhs type : %s \n",
      71        26367 :              get_tree_code_name (TREE_CODE (lhs)));
      72              : 
      73              :   /* This will filter some normal cases too.  Ex.  usage of array.  */
      74        30369 :   if (TREE_CODE (lhs) != SSA_NAME)
      75              :     return false;
      76              : 
      77              :   /* Check uses only when m_output_crc is known.  */
      78        30363 :   if (m_output_crc)
      79        28636 :     if (is_used_outside_the_loop (lhs))
      80              :       return false;
      81              : 
      82        30363 :   if (gimple_num_ops (gs) != 2 && gimple_num_ops (gs) != 3)
      83              :     {
      84            0 :       if (dump_file)
      85            0 :         fprintf (dump_file,
      86              :                  "Warning, encountered unsupported operation, "
      87              :                  "with %s code while executing assign statement!\n",
      88              :                  get_tree_code_name (rhs_code));
      89            0 :       return false;
      90              :     }
      91              : 
      92        30363 :   tree op1 = gimple_assign_rhs1 (gs);
      93        30363 :   tree op2 = nullptr;
      94              : 
      95        30363 :   if (gimple_num_ops (gs) == 3)
      96        27147 :     op2 = gimple_assign_rhs2 (gs);
      97              : 
      98        30363 :   state *current_state = m_states.last ();
      99        30363 :   return current_state->do_operation (rhs_code, op1, op2, lhs);
     100              : }
     101              : 
     102              : /* Add E edge into the STACK if it doesn't have an immediate
     103              :    successor edge going to the loop header.
     104              : 
     105              :    When loop counter is checked in the if condition,
     106              :    we mustn't continue on real path as we want to stop the execution before
     107              :    the second iteration.  */
     108              : 
     109              : bool
     110         6838 : crc_symbolic_execution::add_edge (edge e, auto_vec<edge> &stack)
     111              : {
     112         6838 :   if (EDGE_COUNT (e->dest->succs) == 0)
     113              :     return false;
     114              : 
     115         6838 :   edge next_bb_edge = EDGE_SUCC (e->dest, 0);
     116         6838 :   if (next_bb_edge && next_bb_edge->dest == m_crc_loop->header)
     117              :     {
     118         6102 :       if (dump_file && (dump_flags & TDF_DETAILS))
     119         5155 :         fprintf (dump_file, "Completed one iteration.  "
     120              :                             "Won't iterate loop once more, yet.\n");
     121              : 
     122         6102 :       return keep_states ();
     123              :     }
     124              :   else
     125              :     {
     126          736 :       if (dump_file && (dump_flags & TDF_DETAILS))
     127          551 :         fprintf (dump_file, "Adding the edge into the stack.\n");
     128              : 
     129              :       /* If the result of the condition is true/false,
     130              :          continue execution only by the true/false branch.  */
     131          736 :       stack.quick_push (e);
     132              :     }
     133          736 :   return true;
     134              : }
     135              : 
     136              : /* Add next basic blocks of the conditional block COND_BB
     137              :    for the execution path into the STACK.
     138              :    If the condition depends on symbolic values, keep both edges.
     139              :    If the condition is true, keep true edge, else - false edge.
     140              :    Returns true if addition succeeds.  Otherwise - false.  */
     141              : 
     142              : bool
     143         9993 : crc_symbolic_execution::add_next_bbs (basic_block cond_bb,
     144              :                                       state *new_branch_state,
     145              :                                       auto_vec<edge> &stack)
     146              : {
     147         9993 :   edge true_edge;
     148         9993 :   edge false_edge;
     149         9993 :   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
     150              : 
     151              :   /* When the condition depends on symbolic values.  */
     152         9993 :   if (new_branch_state->get_last_cond_status () == CS_SYM)
     153              :     {
     154              :       /* Supported CRC cases may have only two states.  */
     155         3155 :       if (m_states.length () == 2)
     156              :         {
     157            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
     158            0 :             fprintf (dump_file, "Going to add a new state, "
     159              :                                 "but there's already two states.\n");
     160            0 :           return false;
     161              :         }
     162              :       /* Add true branch's state into the states.
     163              :          False branch's state will be kept in the current state.  */
     164         3155 :       m_states.quick_push (new_branch_state);
     165              : 
     166         3155 :       if (dump_file && (dump_flags & TDF_DETAILS))
     167         2656 :         fprintf (dump_file, "Adding true and false edges into the stack.\n");
     168              : 
     169              :       /* Add outgoing edges to the stack.  */
     170         3155 :       stack.quick_push (false_edge);
     171         3155 :       stack.quick_push (true_edge);
     172              : 
     173         3155 :       return true;
     174              :     }
     175              :   /* When the condition evaluates to true.  */
     176         6838 :   else if (new_branch_state->get_last_cond_status () == CS_TRUE)
     177              :     {
     178         6351 :       if (dump_file && (dump_flags & TDF_DETAILS))
     179         5339 :         fprintf (dump_file, "Condition is true.\n");
     180         6351 :       add_edge (true_edge, stack);
     181              :     }
     182              :   /* When the condition evaluates to false.  */
     183          487 :   else if (new_branch_state->get_last_cond_status () == CS_FALSE)
     184              :     {
     185          487 :       if (dump_file && (dump_flags & TDF_DETAILS))
     186          367 :         fprintf (dump_file, "Condition is false.\n");
     187          487 :       add_edge (false_edge, stack);
     188              :     }
     189              :   else
     190              :     {
     191            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     192            0 :         fprintf (dump_file, "Something went wrong "
     193              :                             "during handling conditional statement.\n");
     194            0 :       return false;
     195              :     }
     196              : 
     197              :   /* When we continue execution of only one path,
     198              :      there's no need of new state.  */
     199         6838 :   delete new_branch_state;
     200         6838 :   return true;
     201              : }
     202              : 
     203              : /* Add conditions depending on symbolic variables in the states.
     204              : 
     205              :    Keep conditions of each branch execution in its state.
     206              :      Ex.
     207              :        if (a == 0)  // a's value is unknown
     208              : 
     209              :        new_branch_state.keep (a==0)
     210              :        current_state.keep (a!=0)
     211              : 
     212              :      The condition is kept in the bit level.
     213              :      For ex.
     214              :      If a's size is 8 and its value is {symb_a, 0, 0, 0, 0, 0, 0, 0},
     215              :      then for a == 0 we'll have symb_a == 0 condition.  */
     216              : 
     217              : bool
     218         9993 : crc_symbolic_execution::add_condition (const gcond *cond,
     219              :                                        state *current_state,
     220              :                                        state *new_branch_state)
     221              : {
     222         9993 :   tree lhs = gimple_cond_lhs (cond);
     223         9993 :   tree rhs = gimple_cond_rhs (cond);
     224         9993 :   switch (gimple_cond_code (cond))
     225              :     {
     226            1 :       case EQ_EXPR:
     227            1 :         {
     228            1 :           new_branch_state->add_equal_cond (lhs, rhs);
     229            1 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     230            0 :             current_state->add_not_equal_cond (lhs, rhs);
     231              :           return true;
     232              :         }
     233         8445 :       case NE_EXPR:
     234         8445 :         {
     235         8445 :           new_branch_state->add_not_equal_cond (lhs, rhs);
     236         8445 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     237         1707 :             current_state->add_equal_cond (lhs, rhs);
     238              :           return true;
     239              :         }
     240            0 :       case GT_EXPR:
     241            0 :         {
     242            0 :           new_branch_state->add_greater_than_cond (lhs, rhs);
     243            0 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     244            0 :             current_state->add_less_or_equal_cond (lhs, rhs);
     245              :           return true;
     246              :         }
     247         1547 :       case LT_EXPR:
     248         1547 :         {
     249         1547 :           new_branch_state->add_less_than_cond (lhs, rhs);
     250         1547 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     251         1448 :             current_state->add_greater_or_equal_cond (lhs, rhs);
     252              :           return true;
     253              :         }
     254            0 :       case GE_EXPR:
     255            0 :         {
     256            0 :           new_branch_state->add_greater_or_equal_cond (lhs, rhs);
     257            0 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     258            0 :             current_state->add_less_than_cond (lhs, rhs);
     259              :           return true;
     260              :         }
     261            0 :       case LE_EXPR:
     262            0 :         {
     263            0 :           new_branch_state->add_less_or_equal_cond (lhs, rhs);
     264            0 :           if (new_branch_state->get_last_cond_status () == CS_SYM)
     265            0 :             current_state->add_greater_than_cond (lhs, rhs);
     266              :           return true;
     267              :         }
     268            0 :       default:
     269            0 :         {
     270            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
     271            0 :             fprintf (dump_file, "Unsupported condition.\n");
     272              :           return false;
     273              :         }
     274              :     }
     275              : }
     276              : 
     277              : /* Create new states for true and false branches.
     278              :    Keep conditions in new created states.  */
     279              : 
     280              : bool
     281         9993 : crc_symbolic_execution::resolve_condition (const gcond *cond,
     282              :                                            auto_vec<edge> &stack)
     283              : {
     284         9993 :   state *current_state = m_states.last ();
     285         9993 :   state *new_branch_state = new state (*current_state);
     286              : 
     287              :   /* Create new states and for true and false branches keep corresponding
     288              :      conditions.  */
     289         9993 :   if (!add_condition (cond, current_state, new_branch_state))
     290              :     return false;
     291              : 
     292              :   /* Add true and false edges to the stack.  */
     293         9993 :   return add_next_bbs (cond->bb, new_branch_state, stack);
     294              : }
     295              : 
     296              : /* If final states are less than two, add new FINAL_STATE and return true.
     297              :    Otherwise, return false.
     298              :    Supported CRC cases may not have more than two final states.  */
     299         6574 : bool crc_symbolic_execution::add_final_state (state *final_state)
     300              : {
     301         6574 :   if (m_final_states.length () < 2)
     302         6574 :       m_final_states.quick_push (final_state);
     303              :   else
     304              :     {
     305            0 :       if (dump_file)
     306            0 :         fprintf (dump_file,
     307              :                  "There are already two final states\n");
     308            0 :       return false;
     309              :     }
     310         6574 :     return true;
     311              : }
     312              : 
     313              : /* Keep the state of the executed path in final states.  */
     314              : 
     315         6574 : bool crc_symbolic_execution::keep_states ()
     316              : {
     317         6574 :   if (m_states.is_empty ())
     318              :     return false;
     319              : 
     320         6574 :   if (!add_final_state (m_states.last ()))
     321              :     {
     322            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     323            0 :         fprintf (dump_file, "Couldn't add final state.\n");
     324            0 :       return false;
     325              :     }
     326              : 
     327         6574 :   m_states.pop ();
     328         6574 :   return true;
     329              : }
     330              : 
     331              : /* Execute gimple statements of BB.
     332              :    Keeping values of variables in the state.  */
     333              : 
     334              : bool
     335        16376 : crc_symbolic_execution::execute_bb_gimple_statements (basic_block bb,
     336              :                                                       auto_vec<edge> &stack)
     337              : {
     338        32752 :   for (gimple_stmt_iterator bsi = gsi_start_bb (bb);
     339        55617 :        !gsi_end_p (bsi); gsi_next (&bsi))
     340              :     {
     341        49246 :       gimple *gs = gsi_stmt (bsi);
     342        49246 :       if (dump_file && (dump_flags & TDF_DETAILS))
     343              :         {
     344        40340 :           fprintf (dump_file, "Executing ");
     345        40340 :           print_gimple_stmt (dump_file, gs, dump_flags);
     346              :         }
     347        49246 :       switch (gimple_code (gs))
     348              :         {
     349        30369 :           case GIMPLE_ASSIGN:
     350        30369 :             {
     351        30369 :               if (!execute_assign_statement (as_a<const gassign *> (gs)))
     352        16376 :                 return false;
     353              :               break;
     354              :             }
     355         9993 :           case GIMPLE_COND:
     356         9993 :             {
     357         9993 :               return resolve_condition (as_a<const gcond *> (gs), stack);
     358              :             }
     359              :           /* Just skip debug statements.  */
     360              :           case GIMPLE_DEBUG:
     361              :             break;
     362            6 :           default:
     363            6 :             {
     364            6 :               if (dump_file)
     365            6 :                 fprintf (dump_file,
     366              :                          "Warning, encountered unsupported statement, "
     367              :                          "while executing gimple statements!\n");
     368              :               return false;
     369              :             }
     370              :         }
     371              :     }
     372              : 
     373              :   /* Add each outgoing edge of the current block to the stack,
     374              :      despite the edges going to the loop header.
     375              :      This code isn't reachable if the last statement of the basic block
     376              :      is a conditional statement or return statement.
     377              :      Those cases are handled separately.
     378              :      We mustn't encounter edges going to the CRC loop header.  */
     379              : 
     380         6371 :   edge out_edge;
     381         6371 :   edge_iterator ei;
     382        12742 :   FOR_EACH_EDGE (out_edge, ei, bb->succs)
     383         6371 :     if (out_edge->dest != m_crc_loop->header)
     384         6371 :       stack.quick_push (out_edge);
     385              :     else
     386              :       return false;
     387              : 
     388              :   return true;
     389              : }
     390              : 
     391              : /* Assign values of phi instruction to its result.
     392              :    Keep updated values in the state.  */
     393              : 
     394              : bool
     395        12945 : crc_symbolic_execution::execute_bb_phi_statements (basic_block bb,
     396              :                                                    edge incoming_edge)
     397              : {
     398        19519 :   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     399         6574 :        gsi_next (&gsi))
     400              :     {
     401         6574 :       gphi *phi = gsi.phi ();
     402         6574 :       tree lhs = gimple_phi_result (phi);
     403              : 
     404              :       /* Check uses only when m_output_crc is known.  */
     405         6574 :       if (m_output_crc)
     406         6313 :         if (is_used_outside_the_loop (lhs))
     407            0 :           return false;
     408              : 
     409              :       /* Don't consider virtual operands.  */
     410        13148 :       if (virtual_operand_p (lhs))
     411            0 :         continue;
     412              : 
     413         6574 :       if (dump_file && (dump_flags & TDF_DETAILS))
     414              :         {
     415         5509 :           fprintf (dump_file, "Determining the value "
     416              :                               "for the following phi.\n");
     417         5509 :           print_gimple_stmt (dump_file, phi, dump_flags);
     418              :         }
     419              : 
     420         6574 :       tree rhs = PHI_ARG_DEF_FROM_EDGE (phi, incoming_edge);
     421              : 
     422         6574 :       state *current_state = m_states.last ();
     423         6574 :       if (!current_state->do_operation (VAR_DECL, rhs, nullptr, lhs))
     424              :         return false;
     425              :     }
     426        12945 :   return true;
     427              : }
     428              : 
     429              : /* Execute all statements of BB.
     430              :    Keeping values of variables in the state.  */
     431              : 
     432              : bool
     433        12945 : crc_symbolic_execution::execute_bb_statements (basic_block bb,
     434              :                                                edge incoming_edge,
     435              :                                                auto_vec<edge> &stack)
     436              : {
     437        12945 :   if (!execute_bb_phi_statements (bb, incoming_edge))
     438              :     return false;
     439              : 
     440        12945 :   return execute_bb_gimple_statements (bb, stack);
     441              : }
     442              : 
     443              : /* If the phi statements' result variables have initial constant value in the
     444              :    beginning of the loop, initialize those variables.  */
     445              : 
     446              : void
     447          241 : assign_known_vals_to_header_phis (state *state, class loop *crc_loop)
     448              : {
     449          241 :   basic_block bb = crc_loop->header;
     450         1086 :   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     451          845 :        gsi_next (&gsi))
     452              :     {
     453              : 
     454          845 :       gphi *phi = gsi.phi ();
     455          845 :       tree lhs = gimple_phi_result (phi);
     456              : 
     457              :       /* Don't consider virtual operands.  */
     458         1690 :       if (virtual_operand_p (lhs))
     459           24 :         continue;
     460              : 
     461          821 :       tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi,
     462              :                                                loop_preheader_edge (crc_loop));
     463          821 :       if (TREE_CODE (inital_val) == INTEGER_CST)
     464              :         {
     465          488 :           if (dump_file && (dump_flags & TDF_DETAILS))
     466              :             {
     467          365 :               fprintf (dump_file, "First value of phi is a constant, "
     468              :                                   "assigning the number to ");
     469          365 :               print_generic_expr (dump_file, lhs, dump_flags);
     470          365 :               fprintf (dump_file, " variable.\n");
     471              :             }
     472          488 :           state->do_operation (VAR_DECL, inital_val,
     473              :                                nullptr, lhs);
     474              :         }
     475              :     }
     476          241 : }
     477              : 
     478              : /* If the phi statements' result variables have initial constant value in the
     479              :    beginning of the loop, initialize those variables with
     480              :    the value calculated during the previous iteration.  */
     481              : 
     482              : bool
     483         2917 : assign_calc_vals_to_header_phis (const vec<state *> &prev_states,
     484              :                                  state *curr_state,
     485              :                                  class loop *crc_loop)
     486              : {
     487         2917 :   basic_block bb = crc_loop->header;
     488        13502 :   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     489        10585 :        gsi_next (&gsi))
     490              :     {
     491        10585 :       gphi *phi = gsi.phi ();
     492        10585 :       tree lhs = gimple_phi_result (phi);
     493              : 
     494              :       /* Don't consider virtual operands.  */
     495        21170 :       if (virtual_operand_p (lhs))
     496          163 :         continue;
     497        10422 :       tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi,
     498              :                                                loop_preheader_edge (crc_loop));
     499        10422 :       if (TREE_CODE (inital_val) == INTEGER_CST)
     500              :         {
     501         5848 :           tree input_tree = PHI_ARG_DEF_FROM_EDGE (phi,
     502              :                                                    loop_latch_edge (crc_loop));
     503         5848 :           value * val_st1 = prev_states[0]->get_value (input_tree),
     504         5848 :               *val_st2 = prev_states[1]->get_value (input_tree);
     505         5848 :           if (!state::is_bit_vector (val_st1)
     506         5848 :               || !state::is_bit_vector (val_st2))
     507              :             {
     508            0 :               if (dump_file && (dump_flags & TDF_DETAILS))
     509              :                 {
     510            0 :                   fprintf (dump_file, "The calculated values of  ");
     511            0 :                   print_generic_expr (dump_file, input_tree, dump_flags);
     512            0 :                   fprintf (dump_file, " variable is not constant.\n");
     513              :                 }
     514            0 :               return false;
     515              :             }
     516         5848 :           else if (!state::check_const_value_equality (val_st1, val_st2))
     517              :             {
     518            0 :               if (dump_file && (dump_flags & TDF_DETAILS))
     519              :                 {
     520            0 :                   fprintf (dump_file, "The calculated values of  ");
     521            0 :                   print_generic_expr (dump_file, input_tree, dump_flags);
     522            0 :                   fprintf (dump_file, " variable is different in the previous "
     523              :                                       "iteration paths.\n");
     524              :                 }
     525            0 :               return false;
     526              :             }
     527              :           else
     528              :             {
     529         5848 :               if (dump_file && (dump_flags & TDF_DETAILS))
     530              :                 {
     531         4972 :                   fprintf (dump_file, "Assigning calculated number to ");
     532         4972 :                   print_generic_expr (dump_file, lhs, dump_flags);
     533         4972 :                   fprintf (dump_file, " variable.\n");
     534              :                 }
     535         5848 :               unsigned HOST_WIDE_INT calc_number
     536         5848 :                   = state::make_number (val_st1);
     537         5848 :               tree calc_num_tree = build_int_cstu (TREE_TYPE (lhs),
     538         5848 :                                                    calc_number);
     539         5848 :               curr_state->do_operation (VAR_DECL, calc_num_tree, nullptr, lhs);
     540              :             }
     541              :         }
     542              :     }
     543         2917 :   return true;
     544              : }
     545              : 
     546              : /* Create initial state of the CRC_LOOP's header BB variables which have
     547              :    constant values.
     548              :    If it is the first iteration of the loop, initialise variables with the
     549              :    initial values, otherwise initialise the variable with the value calculated
     550              :    during the previous execution.  */
     551              : 
     552              : state *
     553         3158 : crc_symbolic_execution::create_initial_state (class loop *crc_loop)
     554              : {
     555         3158 :   state *curr_state = new state;
     556         3158 :   if (!m_final_states.is_empty ())
     557              :     {
     558         2917 :       if (!assign_calc_vals_to_header_phis (m_final_states, curr_state,
     559              :                                             crc_loop))
     560              :         return nullptr;
     561         2917 :       state::remove_states (&m_final_states);
     562              :     }
     563              :   else
     564          241 :     assign_known_vals_to_header_phis (curr_state, crc_loop);
     565              :   return curr_state;
     566              : }
     567              : 
     568              : /* Symbolically execute the CRC loop, doing one iteration.  */
     569              : 
     570              : bool
     571         3158 : crc_symbolic_execution::symb_execute_crc_loop ()
     572              : {
     573         3158 :   if (dump_file && (dump_flags & TDF_DETAILS))
     574         2659 :     fprintf (dump_file, "\n\nExecuting the loop with symbolic values.\n\n");
     575              : 
     576         3158 :   state *curr_state = create_initial_state (m_crc_loop);
     577         3158 :   if (!curr_state)
     578              :     return false;
     579              : 
     580         3158 :   m_states.quick_push (curr_state);
     581              : 
     582         3158 :   auto_vec<edge> stack (m_crc_loop->num_nodes);
     583              : 
     584         3158 :   basic_block header_bb = m_crc_loop->header;
     585         3158 :   if (!execute_bb_gimple_statements (header_bb, stack))
     586              :     return false;
     587              : 
     588              :   /* Successor BB's are added into the stack
     589              :      from the execute_bb_gimple_statements function.  */
     590        19211 :   while (!stack.is_empty ())
     591              :     {
     592              :       /* Look at the edge on the top of the stack.  */
     593        12895 :       edge e = stack.last ();
     594        12895 :       stack.pop ();
     595              : 
     596              :       /* Get destination block of the edge.  */
     597        12895 :       basic_block dest_bb = e->dest;
     598              : 
     599              :       /* Execute only basic blocks of the m_crc_loop.
     600              :          At the end of the execution path save states in final states.  */
     601        12895 :       if (!flow_bb_inside_loop_p (m_crc_loop, dest_bb))
     602              :         {
     603          472 :           m_is_last_iteration = true;
     604          472 :           if (!keep_states ())
     605              :             return false;
     606          472 :           continue;
     607              :         }
     608              : 
     609              :       /* Execute statements.  */
     610        12423 :       if (!execute_bb_statements (dest_bb, e, stack))
     611              :         return false;
     612              :     }
     613              :   return true;
     614         3158 : }
     615              : 
     616              : /* Determine which bit of the DATA must be 1.
     617              :    We assume that last bit must be 1.  */
     618              : 
     619              : unsigned HOST_WIDE_INT
     620          273 : determine_index (tree data, bool is_shift_left)
     621              : {
     622          273 :   if (is_shift_left)
     623              :    /* This won't work correctly in the case when data's size is larger,
     624              :       but MSB is checked for the middle bit.  */
     625          129 :     return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (data))) - 1;
     626              :   return 0;
     627              : }
     628              : 
     629              : /* Assign appropriate values to data, CRC
     630              :    and other phi results to calculate the polynomial.  */
     631              : 
     632              : void
     633          273 : assign_vals_to_header_phis (state *polynomial_state, class loop *crc_loop,
     634              :                             gphi *crc_phi, gphi *data_phi,
     635              :                             bool is_shift_left)
     636              : {
     637          273 :   basic_block bb = crc_loop->header;
     638         1248 :   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
     639          975 :        gsi_next (&gsi))
     640              :     {
     641              : 
     642          975 :       gphi *phi = gsi.phi ();
     643          975 :       tree lhs = gimple_phi_result (phi);
     644              : 
     645              :       /* Don't consider virtual operands.  */
     646         1950 :       if (virtual_operand_p (lhs))
     647           37 :         continue;
     648              : 
     649          938 :       if ((data_phi && phi == data_phi) || (!data_phi && phi == crc_phi))
     650              :         {
     651          273 :           if (dump_file && (dump_flags & TDF_DETAILS))
     652              :             {
     653          206 :               fprintf (dump_file, "Assigning the required value to ");
     654          206 :               print_generic_expr (dump_file, lhs, dump_flags);
     655          206 :               fprintf (dump_file, " variable.\n");
     656              :             }
     657          273 :           polynomial_state->do_assign_pow2 (lhs,
     658          273 :                                             determine_index (lhs,
     659              :                                                              is_shift_left));
     660              :         }
     661          665 :       else if (phi == crc_phi)
     662              :         {
     663          116 :           if (dump_file && (dump_flags & TDF_DETAILS))
     664              :             {
     665          112 :               fprintf (dump_file, "Assigning 0 value to ");
     666          112 :               print_generic_expr (dump_file, lhs, dump_flags);
     667          112 :               fprintf (dump_file, " variable.\n");
     668              :             }
     669          116 :           polynomial_state->do_operation (VAR_DECL,
     670          116 :                                           build_zero_cst (TREE_TYPE (lhs)),
     671              :                                           nullptr, lhs);
     672              :         }
     673              :       else
     674              :         {
     675          549 :           edge loop_preheader = loop_preheader_edge (crc_loop);
     676          549 :           tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader);
     677          549 :           if (TREE_CODE (inital_val) == INTEGER_CST)
     678              :             {
     679          543 :               if (dump_file && (dump_flags & TDF_DETAILS))
     680              :                 {
     681          410 :                   fprintf (dump_file, "First value of phi is a constant, "
     682              :                                       "assigning the number to ");
     683          410 :                   print_generic_expr (dump_file, lhs, dump_flags);
     684          410 :                   fprintf (dump_file, " variable.\n");
     685              :                 }
     686          543 :               polynomial_state->do_operation (VAR_DECL, inital_val,
     687              :                                               nullptr, lhs);
     688              :             }
     689              :           else
     690              :             {
     691            6 :               if (dump_file && (dump_flags & TDF_DETAILS))
     692              :                 {
     693            6 :                   fprintf (dump_file, "First value of phi isn't constant, "
     694              :                                       "assigning to ");
     695            6 :                   print_generic_expr (dump_file, lhs, dump_flags);
     696            6 :                   fprintf (dump_file, " variable.\n");
     697              :                 }
     698            6 :               polynomial_state->do_operation (VAR_DECL,
     699            6 :                                               build_zero_cst (TREE_TYPE (lhs)),
     700              :                                               nullptr, lhs);
     701              :             }
     702              :         }
     703              :     }
     704          273 : }
     705              : 
     706              : /* Execute the loop, which calculates CRC with initial values,
     707              :    to calculate the polynomial.  */
     708              : 
     709              : bool
     710          273 : crc_symbolic_execution::execute_crc_loop (gphi *crc_phi,
     711              :                                           gphi *data_phi,
     712              :                                           bool is_shift_left)
     713              : {
     714          273 :   if (dump_file && (dump_flags & TDF_DETAILS))
     715          206 :     fprintf (dump_file, "\n\nTrying to calculate the polynomial.\n\n");
     716              : 
     717          273 :   m_states.quick_push (new state);
     718              : 
     719          273 :   basic_block bb = m_crc_loop->header;
     720          273 :   assign_vals_to_header_phis (m_states.last (), m_crc_loop, crc_phi, data_phi,
     721              :                               is_shift_left);
     722              : 
     723          273 :   auto_vec<edge> stack (m_crc_loop->num_nodes);
     724              : 
     725          273 :   if (!execute_bb_gimple_statements (bb, stack))
     726              :     return false;
     727              : 
     728              :   /* stack may not be empty.  Successor BB's are added into the stack
     729              :      from the execute_bb_gimple_statements function.  */
     730          783 :   while (!stack.is_empty ())
     731              :     {
     732              :       /* Look at the edge on the top of the stack.  */
     733          522 :       edge e = stack.last ();
     734          522 :       stack.pop ();
     735              : 
     736              :       /* Get dest block of the edge.  */
     737          522 :       basic_block bb = e->dest;
     738              : 
     739              :       /* Execute only basic blocks of the m_crc_loop.  */
     740          522 :       if (!flow_bb_inside_loop_p (m_crc_loop, bb))
     741            0 :         continue;
     742              : 
     743              :       /* Execute statements.  */
     744          522 :       if (!execute_bb_statements (bb, e, stack))
     745              :         return false;
     746              :     }
     747              : 
     748          261 :   if (m_final_states.length () != 1)
     749              :     {
     750            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     751            0 :         fprintf (dump_file, "The number of states is not one when executed "
     752              :                             "the loop for calculating the polynomial.\n");
     753            0 :       return false;
     754              :     }
     755              :   return true;
     756          273 : }
     757              : 
     758              : /* Return true if all bits of the POLYNOMIAL are constants (0 or 1).
     759              :    Otherwise return false.  */
     760              : 
     761              : bool
     762          261 : polynomial_is_known (const value *polynomial)
     763              : {
     764         6949 :   for (size_t i = 0; i < polynomial->length (); i++)
     765              :     {
     766         6688 :       if (!is_a<bit *> ((*polynomial)[i]))
     767              :         return false;
     768              :     }
     769              :   return true;
     770              : }
     771              : 
     772              : /* Execute the loop, which is expected to calculate CRC,
     773              :    to extract polynomial, assigning real numbers to CRC and data.
     774              :    Returns a pair, first value of the pair is the tree containing
     775              :    the value of the polynomial, second is the calculated polynomial.
     776              :    The pair may contain nullptr.  */
     777              : 
     778              : std::pair <tree, value *>
     779          273 : crc_symbolic_execution::extract_polynomial (gphi *crc_phi, gphi *data_phi,
     780              :                                             tree calculated_crc,
     781              :                                             bool is_shift_left)
     782              : {
     783          273 :   if (!execute_crc_loop (crc_phi, data_phi, is_shift_left))
     784           12 :     return std::make_pair (nullptr, nullptr);
     785              : 
     786          261 :   if (m_final_states.length () != 1)
     787              :     {
     788            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     789            0 :         fprintf (dump_file, "The number of states isn't one "
     790              :                             "after executing the loop.\n");
     791            0 :       return std::make_pair (nullptr, nullptr);
     792              :     }
     793          261 :   state *polynomial_state = m_final_states.last ();
     794              : 
     795              :   /* CALCULATED_CRC contains the value of the polynomial
     796              :      after one iteration of the loop.  */
     797          261 :   if (dump_file && (dump_flags & TDF_DETAILS))
     798              :     {
     799          194 :       fprintf (dump_file, "Getting the value of ");
     800          194 :       print_generic_expr (dump_file, calculated_crc, dump_flags);
     801          194 :       fprintf (dump_file, " variable.\n");
     802              :     }
     803              : 
     804              :   /* Get the value (bit vector) of the tree (it may be the polynomial).  */
     805          261 :   value *polynomial = polynomial_state->get_value (calculated_crc);
     806          261 :   if (!polynomial)
     807              :     {
     808            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     809            0 :         fprintf (dump_file, "Polynomial's value is null.\n");
     810            0 :       return std::make_pair (nullptr, nullptr);
     811              :     }
     812              : 
     813          261 :   if (dump_file && (dump_flags & TDF_DETAILS))
     814              :     {
     815              :       /* Note: It may not be the real polynomial.
     816              :          If it's a bit reflected CRC,
     817              :          then to get a real polynomial,
     818              :          it must be reflected and 1 bit added.  */
     819          194 :       fprintf (dump_file, "Polynomial's value is ");
     820          194 :       state::print_value (polynomial);
     821              :     }
     822              : 
     823              :   /* Check that polynomial's all bits are constants.  */
     824          261 :   if (!polynomial_is_known (polynomial))
     825              :     {
     826            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     827            0 :         fprintf (dump_file, "Polynomial's value is not constant.\n");
     828            0 :       return std::make_pair (nullptr, nullptr);
     829              :     }
     830              : 
     831          261 :   return std::make_pair (calculated_crc, polynomial);
     832              : }
     833              : 
     834              : 
     835              : /**************************** LFSR MATCHING *********************************/
     836              : 
     837              : 
     838              : /* Return true if CONST_BIT value equals to 1.
     839              :    Otherwise, return false.  */
     840              : 
     841              : bool
     842        36090 : is_one (value_bit *const_bit)
     843              : {
     844        36090 :   return is_a<bit *> (const_bit)
     845        36090 :          && (as_a<bit *> (const_bit))->get_val () == 1;
     846              : }
     847              : 
     848              : /* Return true if BIT is symbolic,
     849              :    its index is same as LFSR bit's index (LFSR_BIT_INDEX)
     850              :    and the origin is same as CRC_ORIGIN.  */
     851              : 
     852              : bool
     853       205950 : is_a_valid_symb (value_bit *bit, tree crc_origin, size_t lfsr_bit_index)
     854              : {
     855       205950 :   if (!is_a<symbolic_bit *> (bit))
     856              :     return false;
     857              : 
     858       205950 :   symbolic_bit *sym_bit = as_a<symbolic_bit *> (bit);
     859       205950 :   bool is_correct_index = (sym_bit->get_index () == lfsr_bit_index);
     860       205950 :   bool is_same_crc_origin = (sym_bit->get_origin () == crc_origin);
     861       205950 :   return is_correct_index && is_same_crc_origin;
     862              : }
     863              : 
     864              : /* Return true if the BIT is a valid crc[LFSR_BIT_INDEX] ^ 1,
     865              :    where i is a whole number and left part's origin is same as CRC_ORIGIN.
     866              :    LFSR_BIT_INDEX is the index of the LFSR bit from the same position as in CRC.
     867              : 
     868              :    If there is lfsr[8] at LFSR value vectors' 9-th bit,
     869              :    when in the CRC vectors' 9-th bit's value must be
     870              :    crc[8].
     871              : 
     872              :    Otherwise, return false.  */
     873              : 
     874              : bool
     875        36090 : is_a_valid_xor_one (value_bit *bit, tree crc_origin, size_t lfsr_bit_index)
     876              : {
     877        36090 :   if (is_a<bit_xor_expression *> (bit))
     878              :     {
     879        36090 :       bit_xor_expression *xor_exp = as_a<bit_xor_expression *> (bit);
     880        36090 :       if (is_one (xor_exp->get_right ()))
     881        36090 :         return is_a_valid_symb (xor_exp->get_left (), crc_origin,
     882        36090 :                                 lfsr_bit_index);
     883              :       return false;
     884              :     }
     885              :   return false;
     886              : }
     887              : 
     888              : /* Return true, if CONDITION_EXP checks CRC's MSB/LSB value
     889              :    (under which xor is/not done).
     890              :    Otherwise, return false.  */
     891              : 
     892              : bool
     893         6308 : may_be_xors_condition (tree crc_origin, value_bit *condition_exp,
     894              :                        size_t sb_index)
     895              : {
     896         6308 :   if (!crc_origin)
     897              :     return false;
     898              : 
     899         6308 :   if (!condition_exp)
     900              :     return false;
     901              : 
     902              :   /* The CONDITION_EXP of CRC may be a symbolic bit, if CRC is xor-ed with
     903              :      the data, and updated CRC's significant bit is checked.
     904              :      So, the CONDITION_EXP will be CRC's condition if it's origin is the same as
     905              :      CRC_ORIGIN, and it's index equals to checked significant bit's index.  */
     906         6308 :   if (is_a<symbolic_bit *> (condition_exp))
     907              :     {
     908         2802 :       symbolic_bit *condition_symbolic = as_a<symbolic_bit *> (condition_exp);
     909         2802 :       return crc_origin == condition_symbolic->get_origin ()
     910         2802 :              && sb_index == condition_symbolic->get_index ();
     911              :     }
     912              :     /* The CONDITION_EXP of CRC may be a bit_xor_expression,
     913              :        if CRC and data are xor-ed only for significant bit's check.
     914              :        I.e.  CONDITION_EXP in this case may be crc[]^data[].
     915              :        So, the CONDITION_EXP will be CRC's condition if it's left or right
     916              :        part's origin is the same as CRC_ORIGIN, and it's index equals to checked
     917              :        significant bit's index.  */
     918         3506 :   else if (is_a<bit_xor_expression *> (condition_exp))
     919              :     {
     920         3506 :       bit_xor_expression *condition_xor_exp = as_a<bit_xor_expression *>
     921         3506 :           (condition_exp);
     922         3506 :       if (!(is_a<symbolic_bit *> (condition_xor_exp->get_left ())
     923         3506 :             && is_a<symbolic_bit *> (condition_xor_exp->get_right ())))
     924            2 :         return false;
     925              : 
     926         3504 :       symbolic_bit *cond_left
     927         3504 :           = as_a<symbolic_bit *> (condition_xor_exp->get_left ());
     928         3504 :       symbolic_bit *cond_right
     929         3504 :           = as_a<symbolic_bit *> (condition_xor_exp->get_right ());
     930         3504 :       bool cond_left_is_crc = (crc_origin == cond_left->get_origin ()
     931         3504 :                                && sb_index == cond_left->get_index ());
     932         3504 :       bool cond_right_is_crc = (crc_origin == cond_right->get_origin ()
     933         3504 :                                 && sb_index == cond_right->get_index ());
     934         3504 :       return cond_left_is_crc || cond_right_is_crc;
     935              :     }
     936              :   return false;
     937              : }
     938              : 
     939              : /* Check whether the condition is checked for significant bit being 0 or 1.
     940              :    If IS_ONE is 1, when check whether the significant bit is 1 (xor branch),
     941              :    if 0, whether the significant bit is 0 (not xor branch).  */
     942              : 
     943              : bool
     944         6308 : is_crc_xor_condition (tree crc_origin, unsigned char is_one,
     945              :                       size_t sb_index, state *final_state)
     946              : {
     947              :   /* The CRC cases we detect must contain only one condition related to CRC.  */
     948         6308 :   if (final_state->get_conditions ().elements () != 1)
     949              :     return false;
     950              : 
     951         6308 :   auto condition_iter = final_state->get_conditions ().begin ();
     952         6308 :   if (!is_a<bit_condition *> (*condition_iter))
     953              :     return false;
     954              : 
     955              :   /* If the condition is for checking MSB/LSB, then
     956              :      if is_one is 1 and the condition is for checking MSB/LSB being one, or
     957              :      if is_one is 0 and condition is for checking MSB/LSB being 0
     958              :      return true, otherwise - false.  */
     959         6308 :   value_bit *cond_exp = (*condition_iter)->get_left ();
     960         6308 :   if (may_be_xors_condition (crc_origin, cond_exp, sb_index))
     961              :     {
     962         6306 :       if (!is_a<bit *> ((*condition_iter)->get_right ()))
     963              :         return false;
     964              : 
     965         6306 :       bit_condition *condition = as_a<bit_condition *> (*condition_iter);
     966         6306 :       unsigned char comparison_val
     967         6306 :           = as_a<bit *> ((*condition_iter)->get_right ())->get_val ();
     968         6306 :       if (condition->get_code () == EQ_EXPR)
     969         4601 :         return comparison_val == is_one;
     970         1705 :       if (condition->get_code () == NE_EXPR)
     971         1705 :         return comparison_val != is_one;
     972              :       return false;
     973              :     }
     974              :   return false;
     975              : }
     976              : 
     977              : /* Check whether LSB/MSB of LFSR and calculated (maybe)CRC match.
     978              :    If MSB is checked in the CRC loop, then here we check LSB, or vice versa.
     979              :    CHECKED_SB_VALUE indicates which state of CRC value is checked.
     980              :    If the CHECKED_SB_VALUE is 1 - then xor-ed CRC value is checked,
     981              :    otherwise, not xor-ed is checked.  */
     982              : 
     983              : bool
     984         6306 : given_sb_match (value_bit *crc, value_bit *lfsr,
     985              :                 unsigned short checked_sb_value)
     986              : {
     987              :   /* If LFSR's MSB/LSB value is a constant (0 or 1),
     988              :      then CRC's MSB/LSB must have the same value.  */
     989         6306 :   if (is_a<bit *> (lfsr))
     990              :     {
     991          736 :       if (!((is_a<bit *> (crc)
     992          368 :              && as_a<bit *> (crc)->get_val ()
     993          368 :                 == as_a<bit *> (lfsr)->get_val ())))
     994            0 :         return false;
     995              :       return true;
     996              :     }
     997              :     /* If LFSR's MSB/LSB value is a symbolic_bit
     998              :        (that means MSB/LSB of the polynomial is 1),
     999              :        then CRC's MSB/LSB must be equal to CHECKED_SB_VALUE.  */
    1000         5938 :   else if (is_a<symbolic_bit *> (lfsr))
    1001              :     {
    1002         5938 :       if (!(is_a<bit *> (crc)
    1003         5938 :             && (as_a<bit *> (crc)->get_val () == checked_sb_value)))
    1004            0 :         return false;
    1005              :       return true;
    1006              :     }
    1007              :   return false;
    1008              : }
    1009              : 
    1010              : /* Check whether significant bit of LFSR and calculated (maybe)CRC match.  */
    1011              : 
    1012              : bool
    1013         6306 : sb_match (const value *lfsr, const value *crc_value, size_t sb_index,
    1014              :           size_t it_end, unsigned short value)
    1015              : {
    1016              :   /* If it's bit-forward CRC, check 0 bit's value.  */
    1017         6306 :   if (sb_index == it_end - 1)
    1018              :     {
    1019         3408 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1020         3008 :         fprintf (dump_file, "Checking 0 bit.\n");
    1021              : 
    1022         3408 :       if (!given_sb_match ((*crc_value)[0], (*lfsr)[0], value))
    1023              :         return false;
    1024              :     }
    1025              :     /* If it's bit-reversed CRC, check last bit's value.  */
    1026         2898 :   else if (sb_index == 0)
    1027              :     {
    1028         2898 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1029         2304 :         fprintf (dump_file, "Checking %zu bit.\n", it_end);
    1030              : 
    1031         2898 :       if (!given_sb_match ((*crc_value)[it_end], (*lfsr)[it_end], value))
    1032              :         return false;
    1033              :     }
    1034              :   else
    1035              :     {
    1036            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1037            0 :         fprintf (dump_file, "Significant bit index is incorrect.\n");
    1038              :     }
    1039              :   return true;
    1040              : }
    1041              : 
    1042              : /* Match the CRC to the LFSR, where CRC's all bit values are
    1043              :    symbolic_bit or symbolic_bit ^ 1, besides MSB/LSB (it may be constant).  */
    1044              : 
    1045              : bool
    1046         6306 : lfsr_and_crc_bits_match (const value *lfsr, const value *crc_state,
    1047              :                          tree crc_origin, size_t i, size_t it_end,
    1048              :                          size_t sb_index, unsigned short checked_sb_value)
    1049              : {
    1050              : 
    1051              :   /* Check whether significant bits of LFSR and CRC match.  */
    1052         6306 :   if (!sb_match (lfsr, crc_state, sb_index, it_end, checked_sb_value))
    1053              :     return false;
    1054              : 
    1055       212256 :   for (; i < it_end; i++)
    1056              :     {
    1057       205950 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1058       175296 :         fprintf (dump_file, "Checking %zu bit.\n", i);
    1059              : 
    1060              :       /* Check the case when in lfsr we have LFSR (i)^LFSR (SBi),
    1061              :          where 0<i<LFSR_size and SBi is the index of MSB/LSB (LFSR_size-1/0).
    1062              :          In that case in crc_state (resulting CRC)
    1063              :          we must have crc (i) ^ 1 case, when condition is true
    1064              :          and crc (i) when condition is false,
    1065              :          (as CRC is xor-ed with the polynomial only if the LSB/MSB is one)
    1066              :          where k is a whole number.  */
    1067       205950 :       if (is_a<bit_xor_expression *> ((*lfsr)[i]))
    1068              :         {
    1069        72180 :           size_t index = (as_a<bit_xor_expression *> ((*lfsr)[i]))->get_left ()
    1070        72180 :               ->get_index ();
    1071              :           /* Check CRC value of xor branch.  */
    1072        72180 :           if (checked_sb_value == 1)
    1073              :             {
    1074        36090 :               if (!(is_a_valid_xor_one ((*crc_state)[i], crc_origin, index)))
    1075              :                 return false;
    1076              :             }
    1077              :           else /* Check CRC value of not xor branch.  */
    1078              :             {
    1079        36090 :               if (!(is_a_valid_symb ((*crc_state)[i], crc_origin, index)))
    1080              :                 return false;
    1081              :             }
    1082              :         }
    1083              :         /* Check the case when in LFSR we have LFSR (i), where 0<i<LFSR_size.
    1084              :            In that case in resulting CRC we must have crc (i) case,
    1085              :            when condition is true or condition is false.
    1086              :            If we have just LFSR (i), that means polynomial's i ± 1 bit is 0,
    1087              :            so despite CRC is xor-ed or not, we will have crc (i).  */
    1088       133770 :       else if (is_a<symbolic_bit *> ((*lfsr)[i]))
    1089              :         {
    1090       133770 :           size_t index = (as_a<symbolic_bit *> ((*lfsr)[i]))->get_index ();
    1091       133770 :           if (!(is_a_valid_symb ((*crc_state)[i], crc_origin, index)))
    1092              :             return false;
    1093              :         }
    1094              :       else
    1095              :         {
    1096            0 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1097            0 :             fprintf (dump_file, "Not expected expression in LFSR.\n");
    1098            0 :           return false;
    1099              :         }
    1100              :     }
    1101              :   return true;
    1102              : }
    1103              : 
    1104              : /* Return origin of CRC_BIT.
    1105              :    The first tree in loop, from which CRC's calculation is started.  */
    1106              : 
    1107              : tree
    1108         8287 : get_origin_of_crc_from_symb_bit (value_bit *crc_bit)
    1109              : {
    1110         8287 :   if (is_a<symbolic_bit *> (crc_bit))
    1111         6308 :     return as_a<symbolic_bit *> (crc_bit)->get_origin ();
    1112              :   return nullptr;
    1113              : }
    1114              : 
    1115              : /* Return origin of CRC_BIT.  The first tree in loop, from which CRC's
    1116              :    calculation is started.  If the CRC_BIT is symbolic value, return its origin,
    1117              :    otherwise return its left part's origin (right must be 1 if its CRC's
    1118              :    value). */
    1119              : 
    1120              : tree
    1121         6308 : get_origin_of_crc (value_bit *crc_bit)
    1122              : {
    1123         6308 :   tree origin = get_origin_of_crc_from_symb_bit (crc_bit);
    1124         6308 :   if (origin)
    1125              :     return origin;
    1126         1979 :   else if (is_a<bit_xor_expression *> (crc_bit))
    1127              :     {
    1128         1979 :       value_bit *crc_bit_left
    1129         1979 :           = as_a<bit_xor_expression *> (crc_bit)->get_left ();
    1130         1979 :       return get_origin_of_crc_from_symb_bit (crc_bit_left);
    1131              :     }
    1132              :   return nullptr;
    1133              : }
    1134              : 
    1135              : /* Determine and initialize significant bit index
    1136              :    (if MSB is checked for CRC, then it's LSB index, and vice versa)
    1137              :    and the remaining part's begin and end.
    1138              :    SB_INDEX is the significant bit index.
    1139              :    IT_BEG is the beginning of the remaining part.
    1140              :    IT_END is the end of the remaining part.  */
    1141              : 
    1142              : void
    1143         3155 : init_sb_index_and_other_part_begin_end (size_t &it_beg, size_t &it_end,
    1144              :                                         size_t &sb_index, size_t crc_size,
    1145              :                                         bool is_bit_forward)
    1146              : {
    1147         3155 :   it_end = crc_size;
    1148         3155 :   if (is_bit_forward)
    1149              :     {
    1150         1704 :       sb_index = it_end - 1;
    1151         1704 :       it_beg = 1;
    1152              :     }
    1153              :   else
    1154              :     {
    1155         1451 :       it_beg = 0;
    1156         1451 :       sb_index = 0;
    1157         1451 :       --it_end;
    1158              :     }
    1159         3155 : }
    1160              : 
    1161              : /* Return true if CRC_STATE matches the LFSR, otherwise - false.
    1162              :    LFSR - is created LFSR value for the given polynomial and CRC size.
    1163              :    CRC_STATE - contains CRC's calculated value and execution path condition.
    1164              :    IT_BEG and IT_END - are the border indexes of the value to be matched.
    1165              :    SB_INDEX - is the significant bit index of the CRC value,
    1166              :               which will be checked separately.
    1167              :               IF MSB is checked for CRC, when sb_index will be the index of LSB.
    1168              :               Otherwise, will be the index of MSB.
    1169              :    CHECKED_SB_VALUE - is the significant bit's value (used for CRC's condition).
    1170              :               If CHECKED_SB_VALUE is 1, it indicates that CRC_STATE is
    1171              :               xor-ed path's state.
    1172              :               If CHECKED_SB_VALUE is 0, then CRC_STATE is the state of the
    1173              :               not xor branch.  */
    1174              : 
    1175              : bool
    1176         6308 : lfsr_matches_crc_state (const value *lfsr, state *crc_state, value *crc_value,
    1177              :                         size_t it_beg, size_t it_end, size_t sb_index,
    1178              :                         unsigned short checked_sb_value)
    1179              : {
    1180         6308 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1181              :     {
    1182         5312 :       fprintf (dump_file, "Starting to match the following CRC value: ");
    1183         5312 :       state::print_value (crc_value);
    1184              :     }
    1185              : 
    1186              :   /* Get the origin (name) of the calculated CRC value.
    1187              :      All bits must have the same origin.  */
    1188         6308 :   tree crc_origin = get_origin_of_crc ((*crc_value)[it_beg]);
    1189         6308 :   if (!crc_origin)
    1190              :     return false;
    1191              : 
    1192         6308 :   if (!is_crc_xor_condition (crc_origin, checked_sb_value, sb_index, crc_state))
    1193              :     return false;
    1194              : 
    1195              :   /* Check whether CRC_VALUE and LFSR bits match.  */
    1196         6306 :   return lfsr_and_crc_bits_match (lfsr, crc_value, crc_origin,
    1197         6306 :                                   it_beg, it_end, sb_index, checked_sb_value);
    1198              : }
    1199              : 
    1200              : /* Return true if in the CRC_VALUE exists xor expression.
    1201              :    Otherwise, return false.  */
    1202              : 
    1203              : bool
    1204         3155 : is_xor_state (value *crc_value, size_t it_beg, size_t it_end)
    1205              : {
    1206         9571 :    for (unsigned j = it_beg; j < it_end; ++j)
    1207         9571 :      if ((*crc_value)[j]->get_type () == BIT_XOR_EXPRESSION)
    1208              :        return true;
    1209              :    return false;
    1210              : }
    1211              : 
    1212              : /* Keep the value of calculated CRC.  */
    1213              : 
    1214              : value *
    1215         6310 : get_crc_val (tree calculated_crc, state *curr_state)
    1216              : {
    1217         6310 :   if (!calculated_crc)
    1218              :     {
    1219            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1220            0 :         fprintf (dump_file, "Couldn't get the potential CRC variable.\n");
    1221            0 :       return nullptr;
    1222              :     }
    1223              : 
    1224              :   /* When the calculated CRC is constant, it's not possible to determine
    1225              :      whether the CRC has been calculated.  */
    1226         6310 :   if (TREE_CODE (calculated_crc) == INTEGER_CST)
    1227              :     {
    1228            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1229            0 :         fprintf (dump_file, "Calculated CRC is a constant.\n");
    1230            0 :       return nullptr;
    1231              :     }
    1232              : 
    1233              :   /* Get calculated return value.  */
    1234         6310 :   value * crc_value = curr_state->get_value (calculated_crc);
    1235              : 
    1236         6310 :   if (!crc_value)
    1237              :     {
    1238            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1239            0 :         fprintf (dump_file, "CRC is not in the state.\n");
    1240            0 :       return nullptr;
    1241              :     }
    1242              :   return crc_value;
    1243              : }
    1244              : 
    1245              : /* Return true if all states from the FINAL_STATES match the LFSR,
    1246              :    otherwise - false.  */
    1247              : 
    1248              : bool
    1249         3158 : all_states_match_lfsr (value *lfsr, bool is_bit_forward, tree calculated_crc,
    1250              :                        const vec<state *> &final_states)
    1251              : {
    1252         3158 :   if (final_states.length () != 2)
    1253              :     {
    1254            3 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1255            3 :         fprintf (dump_file, "The final states count isn't two.\n");
    1256            3 :       return false;
    1257              :     }
    1258              : 
    1259         3155 :   value *crc_xor_value = get_crc_val (calculated_crc, final_states[0]);
    1260         3155 :   value *crc_not_xor_value = get_crc_val (calculated_crc, final_states[1]);
    1261              : 
    1262              :   /* LFSR's size must be equal to CRC's size.  */
    1263         3155 :   if ((crc_xor_value->length () != lfsr->length ())
    1264         3155 :       || (crc_not_xor_value->length () != lfsr->length ()))
    1265            0 :     return false;
    1266              : 
    1267              :   /* Depending on whether it is bit-forward or reversed CRC,
    1268              :      determine in which significant bit new value is added,
    1269              :      to examine that bit separately.
    1270              :      If in the CRC algorithm MSB (sb_index) is checked to be one for xor,
    1271              :      then here we check LSB separately (marginal bit).
    1272              :      If LSB (sb_index) is checked, then we separate MSB (marginal bit).  */
    1273         3155 :   size_t it_beg, it_end, sb_index;
    1274         3155 :   init_sb_index_and_other_part_begin_end (it_beg, it_end, sb_index,
    1275         3155 :                                           crc_xor_value->length (),
    1276              :                                           is_bit_forward);
    1277              : 
    1278         3155 :     size_t xor_st_index = 0, not_xor_st_index = 1;
    1279              :   /* If first is not xor's state,
    1280              :      then the second state is assumed to be xor's state.  */
    1281         3155 :   if (!is_xor_state (crc_xor_value, it_beg, it_end))
    1282              :     {
    1283            0 :       std::swap (crc_xor_value, crc_not_xor_value);
    1284            0 :       xor_st_index = 1;
    1285            0 :       not_xor_st_index = 0;
    1286              :     }
    1287              : 
    1288              :   /*  If xor-ed CRC value doesn't match the LFSR value, return false.  */
    1289         3155 :   if (!lfsr_matches_crc_state (lfsr, final_states[xor_st_index], crc_xor_value,
    1290              :                                it_beg, it_end, sb_index, 1))
    1291              :     return false;
    1292              : 
    1293              :   /*  If not xor-ed CRC value doesn't match the LFSR value, return false.  */
    1294         3153 :   if (!lfsr_matches_crc_state (lfsr, final_states[not_xor_st_index],
    1295              :                                crc_not_xor_value, it_beg, it_end, sb_index, 0))
    1296              :     return false;
    1297              : 
    1298              :   return true;
    1299              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.