Repository: bytecodealliance/wasmtime
Pull request #5940 (2023-03-06 16:01:56)

Update security release documentation slightly
This modernizes our process doc a bit with what I've been doing for the last security release and the upcoming one as well.

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

- [ ] This has been discussed in issue #..., or if not, please tell us why
  here.
- [ ] A short description of what this does, why it is needed; if the
  description becomes long, the matter should probably be discussed in an issue
  first.
- [ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
  If you don't know who could review this, please indicate so. The list of
  suggested reviewers on the right can help you.

Please ensure all communication adheres to the [code of
conduct](https://github.com/bytecodealliance/wasmtime/blob/master/CODE_OF_CONDUCT.md).
-->



Patch:
diff --git a/cranelift/codegen/src/egraph/elaborate.rs b/cranelift/codegen/src/egraph/elaborate.rs
index d52927ffe..dbb14505a 100644
--- a/cranelift/codegen/src/egraph/elaborate.rs
+++ b/cranelift/codegen/src/egraph/elaborate.rs
@@ -401,6 +401,17 @@ impl<'a> Elaborator<'a> {
                     let arg_values = &self.elab_result_stack[arg_idx..];
 
                     // Compute max loop depth.
+                    //
+                    // Note that if there are no arguments then this instruction
+                    // is allowed to get hoisted up one loop. This is not
+                    // usually used since no-argument values are things like
+                    // constants which are typically rematerialized, but for the
+                    // `vconst` instruction 128-bit constants aren't as easily
+                    // rematerialized. They're hoisted out of inner loops but
+                    // not to the function entry which may run the risk of
+                    // placing too much register pressure on the entire
+                    // function. This is modeled with the `.saturating_sub(1)`
+                    // as the default if there's otherwise no maximum.
                     let loop_hoist_level = arg_values
                         .iter()
                         .map(|&value| {
@@ -423,7 +434,7 @@ impl<'a> Elaborator<'a> {
                             hoist_level
                         })
                         .max()
-                        .unwrap_or(self.loop_stack.len());
+                        .unwrap_or(self.loop_stack.len().saturating_sub(1));
                     trace!(
                         " -> loop hoist level: {:?}; cur loop depth: {:?}, loop_stack: {:?}",
                         loop_hoist_level,
diff --git a/docs/contributing-release-process.md b/docs/contributing-release-process.md
index e66141419..b25d69056 100644
--- a/docs/contributing-release-process.md
+++ b/docs/contributing-release-process.md
@@ -132,28 +132,31 @@ the runbook is merged.
    Advisory**
    * This will not have any CI run, it's recommended to run `./ci/run-tests.sh`
      locally at least.
-   * This will also only be the patch for the `main` branch. You'll need to
-     locally maintain and develop patches for any older releases being backported
-     to. Note that from the major release process there should already be a
-     branch for all older releases.
+   * Develop fixes for all branches that will get a patch release in the
+     advisory, one PR per branch. When the advisory is published all branches
+     will be merged simultaneously. Be sure to run `./ci/run-tests.sh` in each
+     branch.
+   * Don't forget to update `RELEASES.md` with notes about the release on
+     each branch.
 2. **Send a PR for the version bump when an email goes out announcing there will
    be a security release**
    * An email is sent to the bytecodealliance security mailing list ahead of a
      patch release to announce that a patch release will happen. At this time you
      should [trigger the version bump][ci-trigger] against the appropriate
-     `release-x.y.z` branch with the `release-patch` argument.
+     `release-x.y.z` branches with the `release-patch` argument.
    * This will send a PR, but you should not merge it. Instead use this PR and
      the time ahead of the security release to fix any issues with CI. Older
      `release-x.y.z` branches haven't run CI in awhile so they may need to
      backport fixes of one variety or another. DO NOT include the actual fix for
      the security issue into the PR, that comes in the next step.
-3. **Make the patches public**
-   * For the `main` branch this will involve simply publishing the GitHub
-     Security Advisory. Note that CI will run after the advisory's changes are
-     merged in on `main`.
-   * For the backported release branches you should either create a PR targeting
-     these branches or push the changes to the previous version-bump PRs.
-3. **Merge the version-bump PR**
+3. **Make the advisories/patches public**
+   * Publishing the GitHub Security Advisory will merge all the PRs into each
+     branch from the advisory. Note that CI will run for release branches but
+     `main` will probably fail CI since it expected to be merged through the
+     merge queue, but that's ok.
+   * Double-check that CI for release branches finishes and completes
+     successfully.
+4. **Merge the version-bump PR**
    * Like the patch release process this will kick everything else into motion.
      Note that the actual security fixes should be merged either before or as
      part of this PR.


Test patch:
diff --git a/cranelift/filetests/filetests/egraph/licm.clif b/cranelift/filetests/filetests/egraph/licm.clif
index 7d44f53fe..8d6a5ec32 100644
--- a/cranelift/filetests/filetests/egraph/licm.clif
+++ b/cranelift/filetests/filetests/egraph/licm.clif
@@ -36,3 +36,72 @@ block2(v9: i32):
 ; check:      v10 = iconst.i32 1
 ; check:      v4 = iadd.i32 v1, v10
 ; check:      return v4
+
+function %f(i64x2, i32) -> i64x2 {
+block0(v0: i64x2, v1: i32):
+    jump block1(v0, v1)
+
+block1(v2: i64x2, v3: i32):
+    v4 = vconst.i64x2 0x1000000010000000
+    v5 = iadd v2, v4
+    v6 = iconst.i32 1
+    v7 = isub v3, v6
+    brif v7, block1(v5, v7), block2(v5)
+
+block2(v8: i64x2):
+    return v8
+}
+
+; check:  block0(v0: i64x2, v1: i32):
+; nextln:     v4 = vconst.i64x2 const0
+; nextln:     jump block1(v0, v1)
+; check:  block1(v2: i64x2, v3: i32):
+; check:      v6 = iconst.i32 1
+; check:      v7 = isub v3, v6
+; check:      v5 = iadd v2, v4
+; check:      v8 -> v5
+; check:      brif v7, block1(v5, v7), block2
+; check:  block2:
+; check:      return v5
+
+;; don't lift vconst out of 2 loops, only the inner loop, based on the current
+;; heuristic.
+function %f(i64x2, i32, i32) -> i64x2 {
+block0(v0: i64x2, v1: i32, v2: i32):
+    jump block1(v0, v1, v2)
+
+block1(v3: i64x2, v4: i32, v5: i32):
+    jump block2(v3, v4)
+
+block2(v6: i64x2, v7: i32):
+    v8 = vconst.i64x2 0x1000000010000000
+    v9 = iadd v6, v8
+    v10 = iconst.i32 1
+    v11 = isub v7, v10
+    brif v11, block2(v9, v11), block3(v9)
+
+block3(v12: i64x2):
+    v13 = iconst.i32 1
+    v14 = isub v5, v13
+    brif v14, block1(v9, v4, v14), block4
+
+block4:
+    return v12
+}
+
+; check:  block0(v0: i64x2, v1: i32, v2: i32):
+; check:      jump block1(v0, v2)
+; check:  block1(v3: i64x2, v5: i32):
+; check:      v8 = vconst.i64x2 const0
+; check:      jump block2(v3, v1)
+; check:  block2(v6: i64x2, v7: i32):
+; check:      v10 = iconst.i32 1
+; check:      v11 = isub v7, v10
+; check:      v9 = iadd v6, v8
+; check:      brif v11, block2(v9, v11), block3
+; check:  block3:
+; check:      v15 = iconst.i32 1
+; check:      v14 = isub.i32 v5, v15
+; check:      brif v14, block1(v9, v14), block4
+; check:  block4:
+; check:      return v9