diff --git a/Cargo.lock b/Cargo.lock index 7d22780e66a..387b7fbba6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,7 +108,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "const-str", - "getrandom", + "getrandom 0.2.15", "gloo-utils", "js-sys", "pkg-config", @@ -148,7 +148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -384,7 +384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -410,7 +410,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -497,7 +497,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -585,13 +585,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.85" +version = "0.1.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -824,9 +824,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytemuck" @@ -842,9 +842,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cast" @@ -854,9 +854,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.10" +version = "1.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "e4730490333d58093109dc02c23174c3f4d490998c3fed3cc8e82d57afedb9cf" dependencies = [ "shlex", ] @@ -917,9 +917,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.27" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" dependencies = [ "clap_builder", "clap_derive", @@ -947,23 +947,23 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.43" +version = "4.5.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952013545c9c6dca60f491602655b795c6c062ab180c9cb0bccb83135461861" +checksum = "375f9d8255adeeedd51053574fd8d4ba875ea5fa558e86617b07f09f1680c8b6" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1327,7 +1327,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1338,7 +1338,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1461,7 +1461,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1506,7 +1506,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1564,7 +1564,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1603,7 +1603,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1847,7 +1847,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1908,10 +1908,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", +] + [[package]] name = "gimli" version = "0.28.1" @@ -2358,7 +2370,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -2670,7 +2682,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -2959,7 +2971,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -2970,7 +2982,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -3251,7 +3263,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "fm", - "getrandom", + "getrandom 0.2.15", "gloo-utils", "js-sys", "nargo", @@ -3293,7 +3305,7 @@ dependencies = [ "acvm", "build-data", "console_error_panic_hook", - "getrandom", + "getrandom 0.2.15", "gloo-utils", "iter-extended", "js-sys", @@ -3750,22 +3762,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -3923,7 +3935,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", + "toml_edit 0.22.23", ] [[package]] @@ -3969,7 +3981,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -4039,7 +4051,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -4116,7 +4128,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox 0.1.3", "thiserror", ] @@ -4206,7 +4218,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -4239,7 +4251,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.96", + "syn 2.0.98", "walkdir", ] @@ -4295,9 +4307,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.21" +version = "0.23.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" +checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" dependencies = [ "log", "once_cell", @@ -4610,14 +4622,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] name = "serde_json" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -4633,7 +4645,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -4672,7 +4684,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -4955,9 +4967,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -4972,7 +4984,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -4983,13 +4995,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.15.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" dependencies = [ "cfg-if", "fastrand", - "getrandom", + "getrandom 0.3.1", "once_cell", "rustix", "windows-sys 0.59.0", @@ -5051,7 +5063,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -5062,7 +5074,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", "test-case-core", ] @@ -5104,7 +5116,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -5192,7 +5204,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -5267,13 +5279,13 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee" dependencies = [ "indexmap 2.7.1", "toml_datetime", - "winnow 0.6.25", + "winnow 0.7.1", ] [[package]] @@ -5335,7 +5347,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -5418,7 +5430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -5562,9 +5574,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -5604,6 +5616,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.86" @@ -5627,7 +5648,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", "wasm-bindgen-shared", ] @@ -5661,7 +5682,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5708,9 +5729,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.7" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -5914,13 +5935,22 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.25" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310" +checksum = "86e376c75f4f43f44db463cf729e0d3acbf954d13e22c51e26e4c264b4ab545f" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -5962,7 +5992,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", "synstructure", ] @@ -5984,7 +6014,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -6004,7 +6034,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", "synstructure", ] @@ -6025,7 +6055,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -6047,7 +6077,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 62186a0c9e8..09102d530ad 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -145,6 +145,12 @@ pub struct CompileOptions { #[arg(long, hide = true)] pub skip_brillig_constraints_check: bool, + /// Flag to turn on the lookback feature of the Brillig call constraints + /// check, allowing tracking argument values before the call happens preventing + /// certain rare false positives (leads to a slowdown on large rollout functions) + #[arg(long)] + pub enable_brillig_constraints_check_lookback: bool, + /// Setting to decide on an inlining strategy for Brillig functions. /// A more aggressive inliner should generate larger programs but more optimized /// A less aggressive inliner should generate smaller programs @@ -683,6 +689,8 @@ pub fn compile_no_check( }, emit_ssa: if options.emit_ssa { Some(context.package_build_path.clone()) } else { None }, skip_underconstrained_check: options.skip_underconstrained_check, + enable_brillig_constraints_check_lookback: options + .enable_brillig_constraints_check_lookback, enable_brillig_constraints_check: options.enable_brillig_constraints_check, inliner_aggressiveness: options.inliner_aggressiveness, max_bytecode_increase_percent: options.max_bytecode_increase_percent, diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs index 94c0e0554a4..578f0ddb240 100644 --- a/compiler/noirc_evaluator/src/errors.rs +++ b/compiler/noirc_evaluator/src/errors.rs @@ -122,7 +122,7 @@ pub enum InternalWarning { pub enum InternalBug { #[error("Input to Brillig function is in a separate subgraph to output")] IndependentSubgraph { call_stack: CallStack }, - #[error("Brillig function call isn't properly covered by a manual constraint")] + #[error("Brillig function call isn't properly covered by a manual constraint (in space of 1000 instructions)")] UncheckedBrilligCall { call_stack: CallStack }, #[error("Assertion is always false")] AssertFailed { call_stack: CallStack }, diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index d916cd534a7..bd98077df5c 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -71,6 +71,11 @@ pub struct SsaEvaluatorOptions { /// Enable the missing Brillig call constraints check pub enable_brillig_constraints_check: bool, + /// Enable the lookback feature of the Brillig call constraints + /// check (prevents some rare false positives, leads to a slowdown + /// on large rollout functions) + pub enable_brillig_constraints_check_lookback: bool, + /// The higher the value, the more inlined Brillig functions will be. pub inliner_aggressiveness: i64, @@ -116,7 +121,11 @@ pub(crate) fn optimize_into_acir( ssa_level_warnings.extend(time( "After Check for Missing Brillig Call Constraints", options.print_codegen_timings, - || ssa.check_for_missing_brillig_constraints(), + || { + ssa.check_for_missing_brillig_constraints( + options.enable_brillig_constraints_check_lookback, + ) + }, )); }; diff --git a/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs b/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs index 4dbdf18ac72..040357eccb7 100644 --- a/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs +++ b/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs @@ -9,6 +9,7 @@ use crate::ssa::ir::instruction::{Hint, Instruction, InstructionId, Intrinsic}; use crate::ssa::ir::value::{Value, ValueId}; use crate::ssa::ssa_gen::Ssa; use im::HashMap; +use noirc_errors::Location; use rayon::prelude::*; use std::collections::{BTreeMap, BTreeSet, HashSet}; use tracing::trace; @@ -42,7 +43,10 @@ impl Ssa { /// Detect Brillig calls left unconstrained with manual asserts /// and return a vector of bug reports if any have been found - pub(crate) fn check_for_missing_brillig_constraints(&mut self) -> Vec { + pub(crate) fn check_for_missing_brillig_constraints( + &mut self, + enable_lookback: bool, + ) -> Vec { // Skip the check if there are no Brillig functions involved if !self.functions.values().any(|func| func.runtime().is_brillig()) { return vec![]; @@ -56,7 +60,8 @@ impl Ssa { let function_to_process = &self.functions[&fid]; match function_to_process.runtime() { RuntimeType::Acir { .. } => { - let mut context = DependencyContext::default(); + let mut context = + DependencyContext { enable_lookback, ..Default::default() }; context.build(function_to_process, &self.functions); context.collect_warnings(function_to_process) } @@ -117,6 +122,14 @@ struct DependencyContext { // Map of block indices to Brillig call ids that should not be // followed after meeting them search_limits: HashMap, + // Opt-in to use the lookback feature (tracking the argument values + // of a Brillig call before the call happens if their usage precedes + // it). Can prevent certain false positives, at the cost of + // slowing down checking large functions considerably + enable_lookback: bool, + // Code locations of brillig calls already visited (we don't + // need to recheck calls happening in the same unrolled functions) + visited_locations: HashSet, } /// Structure keeping track of value ids descending from Brillig calls' @@ -324,39 +337,55 @@ impl DependencyContext { if let Instruction::Call { func, arguments } = &function.dfg[*instruction] { if let Value::Function(callee) = &function.dfg[*func] { if all_functions[&callee].runtime().is_brillig() { - let results = function.dfg.instruction_results(*instruction); - let current_tainted = - BrilligTaintedIds::new(function, arguments, results); - - // Record arguments/results for each Brillig call for the check. - // - // Do not track Brillig calls acting as simple wrappers over - // another registered Brillig call, update the tainted sets of - // the wrapped call instead - let mut wrapped_call_found = false; - for (_, tainted_call) in self.tainted.iter_mut() { - if current_tainted.is_wrapper(tainted_call) { - tainted_call.update_results_children(results); - wrapped_call_found = true; - break; - } + // Skip already visited locations (happens often in unrolled functions) + let call_stack = function.dfg.get_instruction_call_stack(*instruction); + let location = call_stack.last(); + + // If there is no call stack (happens for tests), consider unvisited + let mut visited = false; + if let Some(location) = location { + visited = self.visited_locations.contains(location); } - if !wrapped_call_found { - // Record the current call, remember the argument values involved - self.tainted.insert(*instruction, current_tainted); - arguments.iter().for_each(|value| { - self.call_arguments - .entry(*value) - .or_default() - .push(*instruction); - }); - - // Set the constraint search limit for the call - self.search_limits.insert( - block_index + BRILLIG_CONSTRAINT_SEARCH_DEPTH, - *instruction, - ); + if !visited { + let results = function.dfg.instruction_results(*instruction); + let current_tainted = + BrilligTaintedIds::new(function, arguments, results); + + // Record arguments/results for each Brillig call for the check. + // + // Do not track Brillig calls acting as simple wrappers over + // another registered Brillig call, update the tainted sets of + // the wrapped call instead + let mut wrapped_call_found = false; + for (_, tainted_call) in self.tainted.iter_mut() { + if current_tainted.is_wrapper(tainted_call) { + tainted_call.update_results_children(results); + wrapped_call_found = true; + break; + } + } + + if !wrapped_call_found { + // Record the current call, remember the argument values involved + self.tainted.insert(*instruction, current_tainted); + arguments.iter().for_each(|value| { + self.call_arguments + .entry(*value) + .or_default() + .push(*instruction); + }); + + // Set the constraint search limit for the call + self.search_limits.insert( + block_index + BRILLIG_CONSTRAINT_SEARCH_DEPTH, + *instruction, + ); + } + + if let Some(location) = location { + self.visited_locations.insert(*location); + } } } } @@ -375,15 +404,17 @@ impl DependencyContext { } }); - // Start tracking calls when their argument value ids first appear, - // or when their instruction id comes up (in case there were - // no non-constant arguments) - for argument in &arguments { - if let Some(calls) = self.call_arguments.get(argument) { - for call in calls { - if let Some(tainted_ids) = self.tainted.get_mut(call) { - tainted_ids.tracking = true; - self.tracking_count += 1; + // If the lookback feature is enabled, start tracking calls when + // their argument value ids first appear, or when their + // instruction id comes up (in case there were no non-constant arguments) + if self.enable_lookback { + for argument in &arguments { + if let Some(calls) = self.call_arguments.get(argument) { + for call in calls { + if let Some(tainted_ids) = self.tainted.get_mut(call) { + tainted_ids.tracking = true; + self.tracking_count += 1; + } } } } @@ -1035,7 +1066,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 1); } @@ -1066,7 +1097,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 1); } @@ -1096,7 +1127,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 0); } @@ -1125,7 +1156,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 0); } @@ -1180,7 +1211,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 1); } @@ -1209,7 +1240,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 2); } @@ -1241,7 +1272,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 0); } @@ -1268,7 +1299,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 1); } @@ -1297,7 +1328,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 0); } @@ -1368,7 +1399,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(false); assert_eq!(ssa_level_warnings.len(), 0); } @@ -1394,7 +1425,7 @@ mod test { "#; let mut ssa = Ssa::from_str(program).unwrap(); - let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(); + let ssa_level_warnings = ssa.check_for_missing_brillig_constraints(true); assert_eq!(ssa_level_warnings.len(), 0); } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/hint.rs b/compiler/noirc_evaluator/src/ssa/opt/hint.rs index 4897799f371..6d7a16a8cfa 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/hint.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/hint.rs @@ -18,6 +18,7 @@ mod tests { expression_width: ExpressionWidth::default(), emit_ssa: None, skip_underconstrained_check: true, + enable_brillig_constraints_check_lookback: false, enable_brillig_constraints_check: false, inliner_aggressiveness: 0, max_bytecode_increase_percent: None,