Background
----------
sched1 runs a preliminary "model schedular" ahead of the main list schedular.
Its sole purpose is to keep register pressure to mimimum [1] and it uses DFA
register depenendency tracking to arrange insns.

   [1] https://gcc.gnu.org/legacy-ml/gcc-patches/2011-12/msg01684.html

                           `The idea was to construct a preliminary
   "model" schedule in which the only objective is to keep register
   pressure to a minimum.  This schedule ignores pipeline characteristics,
   latencies, and the number of available registers.  The maximum pressure
   seen in this initial model schedule (MP) is then the benchmark for ECC(X).`

It starts off with an intial "worklist" of insns w/o any prior dependencies,
scheduling them, adding successors of scheduled insn to the worklist and so
on until all insns in the basic block are done.
It can run into situations where an otherwise to-be-scheduled candidate can't
because it's predecessors haven't been scheduled yet, requiring
"predecessor promotion" implemented in model_promote_predecessors ().
Promotion is essentially bumping INSN model_priority so that it makes it
towards the head of elligible-to-schedule list.

An INSN can have multiple dependencies/predecessor nodes, some of them
being true dependency REG_DEP_TRUE meaning the predecessor register output
is a must have for the INSN to be scheduled.
e.g.
In the sched1 dump below, insn 70 has multiple deps, but 68 and 69 are
true reg deps:

;;      | insn | prio |
;;      |   68 |    3 | r217=r144+r146
;;      |   69 |    5 | r218=flt(r143)
;;      |   70 |    2 | [r217]=r218

;;      insn  code    bb   dep  prio  cost   reservation
;;      ----  ----    --   ---  ----  ----   -----------
;;       70   286     6     6     2     1   alu : FW: 97tnm 91m 83tn 78m 76tn 
72tn
;;                                              : BK: 69t 68t 57n 60n 61n 64n
                                                      ^^^ ^^^

Issue
-----
Currently predecessor promotion bumps the priority of all predecessors
to same value, treating the true deps and the rest alike. This simple
strategy can sometimes cause a subtle inadvertent effect: given the right
"other" conditions (depth, height etc) a non true dependency can get
scheduled ahead of the true dep, increasing the live range between the
true dep and the dependent. This increases the peak register pressure
for the BB. Subsequently this inflated peak register pressure steers
the main list schdular, giving it the lower bound to work with.
Main schedular can make pressure worse (due to instruction latencies
and pipeline models etc) but otherwise it can work with the given
peak pressure. Thus a higher model pressure will ultimately lead to a
less than ideal final schedule.

This subtle effect get crazy exacerbated on RISC-V SPEC2017 Cactu
benchmark.

For the spill2.cpp testcase (reduced from Cactu itself) on RISC-V,
here's what was seen:

  - After idx #6, insn 70 predecessors are promoted (see list above).
    Of the true deps, insn 68 is already schdeuled, insn 69 needs to be.
    insn 69 does get promoted (higher priority 4) but so does insn 60
    (prio 4) with its predecessor insn 58 getting even higher
    promotion (prio 5).

  - The insn 58 and its deps chain end up being scheduled ahead of insn 70
    such that now there are 3 insns seperating it from its direct dep
    insn 69. This blows reg pressure past the spill threshhold of
    sched_class_regs_num[GR_REGS] as evident from the pressure
    summary at the end.

;;      Model schedule:
;;
;;      | idx insn | mpri hght dpth prio |
;;      |   0   56 |    0    8    0   15 | r210=flt(r185#0)     GR_REGS:[25,+0] 
FP_REGS:[0,+1]
;;      |   1   57 |    0    8    1   12 | [r242+low(`e')]=r210 GR_REGS:[25,+0] 
FP_REGS:[1,-1]
;;      |   2   63 |    2    7    0   12 | r215=r141+r183       GR_REGS:[25,+1] 
FP_REGS:[0,+0]
;;      |   3   64 |    1    8    2   11 | r216=[r215]          GR_REGS:[26,-1] 
FP_REGS:[0,+1]
;;      |   4   65 |    0    8    3    8 | r143=fix(r216)       GR_REGS:[25,+1] 
FP_REGS:[1,-1]
;;      |   5   67 |    0    8    4    4 | r146=r143<<0x3       GR_REGS:[26,+1] 
FP_REGS:[0,+0]
;;      |   6   68 |    0    8    5    3 | r217=r144+r146       GR_REGS:[27,+1] 
FP_REGS:[0,+0]

;;      +--- priority of 70 = 3, priority of 69 60 61 = 4

;;      |   7   69 |    4    7    4    5 | r218=flt(r143)        
GR_REGS:[28,+0] FP_REGS:[0,+1]
;;      |   8   58 |    6    4    0    5 | r211=r138+r183        
GR_REGS:[28,+1] FP_REGS:[1,+0]
                                                                         ^^^^^^^
;;      |   9   60 |    5    5    2    4 | r213=[r211]           
GR_REGS:[29,-1] FP_REGS:[1,+1]
;;      |  10   61 |    4    3    0    4 | r214=[r243+low(`o')]  
GR_REGS:[28,+0] FP_REGS:[2,+1]
;;      |  11   70 |    3    8    6    2 | [r217]=r218           
GR_REGS:[28,-1] FP_REGS:[3,-1]
...
...
;; Pressure summary: GR_REGS:29 FP_REGS:3
                            ^^^

Solution
--------
When promoting predecessors, only assign the true deps higher priority.
The rest of predecessors get the same priority as depedant insn.

Implementation
--------------

Predecessor promotion logic can be described in pseudo "C" as follows:

  insn->model_priority = model_next_priority++;
  for (;;)                                                   #0
    {
     FOR_EACH_DEP (insn->insn, SD_LIST_HARD_BACK, sd_it, dep)
       {
        if (pro->insn                                        #1
              && pro->model_priority != model_next_priority
              && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
         {

            pro->model_priority = model_next_priority;       #2

            if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
              {
...
              }
            else // recurse to dependent                     #3
              {
                  pro->next = first;
                  first = pro;
              }
         }                                  // if not schduled
       }                                    // FOR_EACH_DEP

       if (!first)
        break;
       insn = first;
       first = insn->next;
    }                                       // for
   model_next_priority++ ;

 - The core change of this patch is essentially bifurcating #2 to bump the
   priortiy for true dependency more than the rest of deps.

 - An additional gaurd added in #3, to only recurse for true deps;
   otherwise it can end up clobbering the recurse list with same entry
   showing up multiple times, (e.g. an insn could be predecessor of multiple
   dependant insns: as true dep for first and normal dep for the others).

 - The condition #1 also needs to be tightened for the two levels of
   predecessor priorities.

 - The good (and bad) thing is there is a overarching infinite loop #0
   and any coding snafus tend to hit it pretty fast, just by trying to
   bootstrap the toolchain (specially libgcc) or building glibc off of it.

 - There is also a need to track true dependencies in addition to the
   existing all deps of an insn. This is needed at the call-site of
   promotion logic to only invoke promotion when there's unscheduled
   true dependecies.

 - These changes are NOT gated behing the new target hook as it seems
   like the right thing to do anywhere/everywhere.

Improvement measurement
------------------------
Results are convincing On RISC-V (BPI-F3) run of Cactu.
(Build: -Ofast -march=rv64gcv_zba_zbb_zbs)

 Before:
 ------
 7,631,707,552,979      cycles:u                         #    1.600 GHz
 2,630,225,489,010      instructions:u                   #    0.34  insn per 
cycle

 After (just this fix)
 -----
 7,100,864,968,062      cycles:u          ( 7% faster)   #    1.600 GHz
 2,180,957,013,712      instructions:u    (17% fewer)    #    0.31  insn per 
cycle

 Aggregate (with ECC fix)
 ----
 6,736,337,207,427      cycles:u          (12% faster)   #    1.600 GHz
 2,078,712,047,604      instructions:u    (21% fewer)    #    0.31  insn per 
cycle

 ECC fix alone (prev patch)
 ----
 7,153,778,156,281      cycles:u         ( 6% faster)    #    1.600 GHz
 2,143,115,846,207      instructions:u   (18.5% faster)  #    0.30  insn per 
cycle

Significant gains are also seen on aarch64 (QEMU dynamic icounts only)
(Build: -Ofast -march=armv9-a+sve2)

 Before                   : 1,382,403,783,566
 After (just this fix)    : 1,237,532,639,657 (10.4% fewer)
 Aggregate (with ECC fix) : 1,113,896,471,282 (19.4% fewer)
 Just ECC fix (prev patch): 1,264,869,192,921 (8.5% fewer)

TBD
---

On RISC-V the individual gains from model pressure fix (7, 17) and
the ECC fix (6, 18.5) are are not adding up with both fixes (12, 21)
indicating that main list schedular could be undoing some of the
model schedule arrangements (which it does anyways for right
reasons). On aarch64 they seem to be accumulating on top nicely,
atleast in the QEMU icounts reduction.

gcc/ChangeLog:

        PR target/114729
        * haifa-sched.cc (struct model_insn_info): Add field
        unscheduled_true_preds.
        (model_analyze_insns): Initialize unscheduled_true_preds.
        (model_add_successors_to_worklist): Decrement
        unscheduled_true_preds.
        (model_promote_predecessors): Handle true dependencies
        differently than the rest.
        (model_choose_insn): Promote only on pending true dependencies.
        (model_dump_pressure_summary): Print BB index.
        (model_start_schedule): Call dump summary with BB reference.
        * sched-rgn.cc (debug_dependencies): Print predecessors for
        debugging aid.

gcc/testsuite/ChangeLog:

        PR target/114729
        * gcc.target/riscv/sched1-spills/hang1.c: New test.
        * gcc.target/riscv/sched1-spills/hang5.c: New test.
        * gcc.target/riscv/sched1-spills/spill2.cpp: New test.

Signed-off-by: Vineet Gupta <vine...@rivosinc.com>
---
 gcc/haifa-sched.cc                            | 66 ++++++++++++++-----
 gcc/sched-rgn.cc                              | 14 +++-
 .../gcc.target/riscv/sched1-spills/hang1.c    | 32 +++++++++
 .../gcc.target/riscv/sched1-spills/hang5.c    | 60 +++++++++++++++++
 .../gcc.target/riscv/sched1-spills/spill2.cpp | 37 +++++++++++
 5 files changed, 192 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/sched1-spills/hang1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sched1-spills/hang5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/sched1-spills/spill2.cpp

diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc
index f8c42d30d5a4..67f99ce00339 100644
--- a/gcc/haifa-sched.cc
+++ b/gcc/haifa-sched.cc
@@ -1862,6 +1862,9 @@ struct model_insn_info {
 
   /* The number of predecessor nodes that must still be scheduled.  */
   int unscheduled_preds;
+
+  /* The subset of above which have true register dependency.  */
+  int unscheduled_true_preds;
 };
 
 /* Information about the pressure limit for a particular register class.
@@ -3529,7 +3532,20 @@ model_analyze_insns (void)
        insn->old_queue = QUEUE_INDEX (iter);
        QUEUE_INDEX (iter) = QUEUE_NOWHERE;
 
-       insn->unscheduled_preds = dep_list_size (iter, SD_LIST_HARD_BACK);
+       insn->unscheduled_preds = 0;
+       insn->unscheduled_true_preds = 0;
+       /* opencoded dep_list_size () to get true deps as well.  */
+       FOR_EACH_DEP (iter, SD_LIST_HARD_BACK, sd_it, dep)
+         {
+           if (DEBUG_INSN_P (DEP_PRO (dep)))
+             continue;
+           insn->unscheduled_preds++;
+           if (DEP_TYPE (dep) == REG_DEP_TRUE)
+             insn->unscheduled_true_preds++;
+         }
+       gcc_assert (insn->unscheduled_preds
+                   == dep_list_size (iter, SD_LIST_HARD_BACK));
+
        if (insn->unscheduled_preds == 0)
          model_add_to_worklist (insn, NULL, model_worklist);
 
@@ -3661,6 +3677,9 @@ model_add_successors_to_worklist (struct model_insn_info 
*insn)
        {
          con->unscheduled_preds--;
 
+         if (DEP_TYPE (dep) == REG_DEP_TRUE)
+           con->unscheduled_true_preds--;
+
          /* Update the depth field of each true-dependent successor.
             Increasing the depth gives them a higher priority than
             before.  */
@@ -3692,7 +3711,7 @@ model_add_successors_to_worklist (struct model_insn_info 
*insn)
 static void
 model_promote_predecessors (struct model_insn_info *insn)
 {
-  struct model_insn_info *pro, *first;
+  struct model_insn_info *pro, *first, *leaf_true_dep = NULL;
   sd_iterator_def sd_it;
   dep_t dep;
 
@@ -3708,16 +3727,25 @@ model_promote_predecessors (struct model_insn_info 
*insn)
     {
       FOR_EACH_DEP (insn->insn, SD_LIST_HARD_BACK, sd_it, dep)
        {
+         bool true_dep = (DEP_TYPE (dep) == REG_DEP_TRUE);
+
          pro = MODEL_INSN_INFO (DEP_PRO (dep));
          /* The first test is to ignore debug instructions, and instructions
             from other blocks.  */
          if (pro->insn
-             && pro->model_priority != model_next_priority
-             && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
+             && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED
+             && ((true_dep && (pro->model_priority < model_next_priority))
+                 || (!true_dep
+                     && (pro->model_priority < (model_next_priority - 1)))))
            {
-             pro->model_priority = model_next_priority;
+             if (true_dep)
+               pro->model_priority = model_next_priority;
+             else
+               pro->model_priority = model_next_priority - 1;
+
              if (sched_verbose >= 7)
-               fprintf (sched_dump, " %d", INSN_UID (pro->insn));
+               fprintf (sched_dump, " %d=%d", INSN_UID (pro->insn),
+                        pro->model_priority);
              if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
                {
                  /* PRO is already in the worklist, but it now has
@@ -3726,12 +3754,14 @@ model_promote_predecessors (struct model_insn_info 
*insn)
                  model_remove_from_worklist (pro);
                  model_add_to_worklist (pro, NULL, model_worklist);
                }
-             else
+             else if (true_dep)
                {
                  /* PRO isn't in the worklist.  Recursively process
                     its predecessors until we find one that is.  */
                  pro->next = first;
                  first = pro;
+                 if (pro->unscheduled_true_preds == 0)
+                   leaf_true_dep = pro;
                }
            }
        }
@@ -3740,9 +3770,15 @@ model_promote_predecessors (struct model_insn_info *insn)
       insn = first;
       first = insn->next;
     }
-  if (sched_verbose >= 7)
-    fprintf (sched_dump, " = %d\n", model_next_priority);
+  if (leaf_true_dep)
+    {
+      gcc_assert (QUEUE_INDEX (leaf_true_dep->insn) == QUEUE_NOWHERE);
+      gcc_assert (leaf_true_dep->model_priority == model_next_priority);
+      model_add_to_worklist (leaf_true_dep, NULL, model_worklist);
+    }
   model_next_priority++;
+  if (sched_verbose >= 7)
+    fprintf (sched_dump, "  NEXT prio = %d\n", model_next_priority);
 }
 
 /* Pick one instruction from model_worklist and process it.  */
@@ -3760,10 +3796,10 @@ model_choose_insn (void)
       count = param_max_sched_ready_insns;
       while (count > 0 && insn)
        {
-         fprintf (sched_dump, ";;\t+---   %d [%d, %d, %d, %d]\n",
+         fprintf (sched_dump, ";;\t+---   %d [%d, %d, %d, %d][%d]\n",
                   INSN_UID (insn->insn), insn->model_priority,
                   insn->depth + insn->alap, insn->depth,
-                  INSN_PRIORITY (insn->insn));
+                  INSN_PRIORITY (insn->insn), insn->unscheduled_preds);
          count--;
          insn = insn->next;
        }
@@ -3824,7 +3860,7 @@ model_choose_insn (void)
        fprintf (sched_dump, ";;\t+--- promoting insn %d, which is ready\n",
                 INSN_UID (insn->insn));
     }
-  if (insn->unscheduled_preds)
+  if (insn->unscheduled_true_preds)
     /* INSN isn't yet ready to issue.  Give all its predecessors the
        highest priority.  */
     model_promote_predecessors (insn);
@@ -3857,11 +3893,11 @@ model_reset_queue_indices (void)
    to sched_dump.  */
 
 static void
-model_dump_pressure_summary (void)
+model_dump_pressure_summary (basic_block bb)
 {
   int pci, cl;
 
-  fprintf (sched_dump, ";; Pressure summary:");
+  fprintf (sched_dump, ";; Pressure summary (bb %d):", bb->index);
   for (pci = 0; pci < ira_pressure_classes_num; pci++)
     {
       cl = ira_pressure_classes[pci];
@@ -3900,7 +3936,7 @@ model_start_schedule (basic_block bb)
   model_curr_point = 0;
   initiate_reg_pressure_info (df_get_live_in (bb));
   if (sched_verbose >= 1)
-    model_dump_pressure_summary ();
+    model_dump_pressure_summary (bb);
 }
 
 /* Free the information associated with GROUP.  */
diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc
index 3d8cff76aaf9..bedccc9f2b83 100644
--- a/gcc/sched-rgn.cc
+++ b/gcc/sched-rgn.cc
@@ -2855,15 +2855,25 @@ void debug_dependencies (rtx_insn *head, rtx_insn *tail)
       else
        print_reservation (sched_dump, insn);
 
-      fprintf (sched_dump, "\t: ");
+      fprintf (sched_dump, "\t: FW:");
       {
        sd_iterator_def sd_it;
        dep_t dep;
 
        FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
-         fprintf (sched_dump, "%d%s%s ", INSN_UID (DEP_CON (dep)),
+         fprintf (sched_dump, " %d%s%s%s", INSN_UID (DEP_CON (dep)),
+                  DEP_TYPE (dep) == REG_DEP_TRUE ? "t" : "",
                   DEP_NONREG (dep) ? "n" : "",
                   DEP_MULTIPLE (dep) ? "m" : "");
+       if (sched_verbose >= 5)
+         {
+           fprintf (sched_dump, "\n;;\t\t\t\t\t\t: BK:");
+           FOR_EACH_DEP (insn, SD_LIST_HARD_BACK, sd_it, dep)
+             fprintf (sched_dump, " %d%s%s%s", INSN_UID (DEP_PRO (dep)),
+                      DEP_TYPE (dep) == REG_DEP_TRUE ? "t" : "",
+                      DEP_NONREG (dep) ? "n" : "",
+                      DEP_MULTIPLE (dep) ? "m" : "");
+         }
       }
       fprintf (sched_dump, "\n");
     }
diff --git a/gcc/testsuite/gcc.target/riscv/sched1-spills/hang1.c 
b/gcc/testsuite/gcc.target/riscv/sched1-spills/hang1.c
new file mode 100644
index 000000000000..312bea1fede0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sched1-spills/hang1.c
@@ -0,0 +1,32 @@
+/* Reduced from libgcc/_divtc3.c
+   - Interim version of model schedule changes would cause a infinite loop
+     during predecessor promotion.
+
+     insn 11 predecessor promotion called with insn 9 being predecessor
+     of two insn 10 and insn 11.
+
+;;   --- Region Dependences --- b 2 bb 0
+    ...
+;;       10    76     2     1     4     3   alu        : FW: 11tm
+;;                                             : BK: 9t
+;;       11   357     2     6     1     1   alu        : FW:
+;;                                             : BK: 5 6 8 9 10tm 7tm
+    ...
+;;     Model schedule:
+;;
+;;     | idx insn | mpri hght dpth prio |
+;;     |   0    5 |    0    3    0    8 | r138=`a'
+;;     |   1    6 |    0    3    1    7 | r140=[r138]
+;;     |   2    7 |    0    3    2    4 | r139=abs(r140)
+    ...
+;;     +--- priority of 11 = 2, priority of 8=2 9=2 10=3 9=3 8=3  */
+
+
+/* { dg-options "-O2 -fPIC -march=rv64gc_zba_zbb_zbs_zfa -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "O1" "-Og" "-Os" "-Oz" } } */
+
+float a, b;
+void c() {
+  if (__builtin_fabsl(a) < __builtin_fabsl(b))
+    a = 2;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/sched1-spills/hang5.c 
b/gcc/testsuite/gcc.target/riscv/sched1-spills/hang5.c
new file mode 100644
index 000000000000..0edb04223234
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sched1-spills/hang5.c
@@ -0,0 +1,60 @@
+/* Reduced from glibc:iconv/gconv_simple.c
+   - Interim version of model schedule changes would cause a infinite loop
+     during predecessor promotion because true dependency was not getting
+     added to worklist.
+
+     insn 19 is indirect predecessor of multiple insns, but not direct of
+     any in the BB.
+
+;;   --- Region Dependences --- b 4 bb 0
+    ...
+;;       19   275     4     0     2     1   alu        : FW: 26 20
+;;                                             : BK:
+;;       20     5     4     2     2     1   alu        : FW: 26tm
+;;                                             : BK: 15 19
+;;       22   125     4     1     5     3   alu        : FW: 26 25t
+;;                                             : BK: 18tn
+;;       25   104     4     1     2     1   alu        : FW: 26tm
+;;                                             : BK: 22t
+;;       26   353     4     7     1     1   alu        : FW:
+;;                                             : BK: 15 16 19 22 25tm 20tm 18m
+    ...
+;;     Model schedule:
+;;
+;;     | idx insn | mpri hght dpth prio |
+;;     |   0   15 |    0    5    0   10 | r161=r134+r140
+;;     |   1   16 |    0    5    1    9 | r139=zxn([r161+0x4])
+;;     |   2   18 |    0    5    2    6 | [r178+low(`g')]=r139#0
+;;     |   3   22 |    0    5    3    5 | r164=sxn([r134])
+;;     |   4   25 |    0    5    4    2 | r166=r164&0x7
+    ...
+;;     +--- priority of 26 = 1, priority of 19=1 20=2 19=1  NEXT prio = 3
+;;     +--- priority of 26 = 3, priority of 19=3 20=4 19=3  NEXT prio = 5  */
+
+
+/* { dg-options "-O2 -march=rv64gc_zba_zbb_zbs_zfa -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "O1" "-Og" "-Os" "-Oz" } } */
+
+typedef struct {
+  int a;
+  struct {
+    char b[];
+  } c;
+} d;
+struct e {
+  d *f;
+} i;
+char g[4];
+char h;
+void j(struct e *m) {
+  d *k;
+  long a = 0, l;
+  for (; a < (m->f->a & 7); ++a)
+    g[0] = m->f->c.b[a];
+  for (; a < l; a++)
+    k->c.b[a] = h;
+}
+void n() {
+  if (i.f->a & 7)
+    j(&i);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/sched1-spills/spill2.cpp 
b/gcc/testsuite/gcc.target/riscv/sched1-spills/spill2.cpp
new file mode 100644
index 000000000000..cb739ac6a7d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sched1-spills/spill2.cpp
@@ -0,0 +1,37 @@
+/* Reduced from SPEC2017 Cactu ML_BSSN_RHS.cpp
+   Showed spill despite the prior ECC fix (vs. -fno-schedule-insns) due to
+   promotion of non true predecessors (essentally led to this patch).  */
+
+/* { dg-options "-O2 -march=rv64gc -mabi=lp64d -save-temps -fverbose-asm" } */
+/* { dg-final { scan-assembler-times "%sfp" 0 } } */
+
+void a();
+double *b, *c, *d, *f, *g, *h;
+double e, o, q;
+int k, l, n;
+int *m;
+long p;
+void r() {
+  long ai = p;
+  for (;;)
+    for (int j; n; ++j)
+      for (int i(m[0]); i; i++) {
+        long aj = i * j;
+        e = aj;
+        double am = b[aj], ba = am, bf = ba * o;
+        c[aj] = aj = f[aj];
+        double aq = g[aj];
+        double at = ((double *)a)[aj];
+        switch (l)
+        case 2:
+          (&aj)[ai] = (&d[aj])[ai];
+        double ax(aq);
+        double ay(k == 1 ? at : 0);
+        double az = ay;
+        double be = ax;
+        double bg = az * q * be * bf;
+        double bh = bg;
+        h[aj] = bh;
+      }
+}
+
-- 
2.43.0

Reply via email to