From 13c78468159033c637323801d2dc09460bbd71e2 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 8 Sep 2022 12:04:59 -0500 Subject: [PATCH] Cranelift: add a vreg limit check to correctly return an error on too-large inputs. (#4882) Previously, Cranelift panicked (via a a panic in regalloc2) when the virtual-register limit of 2M (2^21) was reached. This resulted in a perplexing and unhelpful failure when the user provided a too-large input (such as the Wasm module in #4865). This PR adds an explicit check when allocating vregs that fails with a "code too large" error when the limit is hit, producing output such as (on the minimized testcase from #4865): ``` Error: failed to compile wasm function 3785 at offset 0xa3f3 Caused by: Compilation error: Code for function is too large ``` Fixes #4865. --- cranelift/codegen/src/machinst/lower.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs index 5e9276cda2..8c21dbb248 100644 --- a/cranelift/codegen/src/machinst/lower.rs +++ b/cranelift/codegen/src/machinst/lower.rs @@ -19,7 +19,7 @@ use crate::machinst::{ LoweredBlock, MachLabel, Reg, SigSet, VCode, VCodeBuilder, VCodeConstant, VCodeConstantData, VCodeConstants, VCodeInst, ValueRegs, Writable, }; -use crate::{trace, CodegenResult}; +use crate::{trace, CodegenError, CodegenResult}; use alloc::vec::Vec; use regalloc2::VReg; use smallvec::{smallvec, SmallVec}; @@ -323,6 +323,10 @@ fn alloc_vregs( let v = *next_vreg; let (regclasses, tys) = I::rc_for_type(ty)?; *next_vreg += regclasses.len(); + if *next_vreg >= VReg::MAX { + return Err(CodegenError::CodeTooLarge); + } + let regs: ValueRegs = match regclasses { &[rc0] => ValueRegs::one(VReg::new(v, rc0).into()), &[rc0, rc1] => ValueRegs::two(VReg::new(v, rc0).into(), VReg::new(v + 1, rc1).into()),