fortrangoingonforty/armfortas / 6681f99

Browse files

Restrict scalar-broadcast routing to known scalar inquiry intrinsics

Authored by espadonne
Committed by mfwolffe
SHA
6681f99495512b0b1a8f6655d3e3f33b735ae526
Parents
ec089b7
Tree
b132017

1 changed file

StatusFile+-
M src/ir/lower/stmt.rs 38 36
src/ir/lower/stmt.rsmodified
@@ -423,37 +423,39 @@ pub(crate) fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &Spanned
423423
                                             } else {
424424
                                                 false
425425
                                             };
426
-                                        // Scalar-returning call assigned to a whole array is a
427
-                                        // broadcast: `x = ieee_value(...)`, `x = sin(scalar_y)`,
428
-                                        // user `x = scalar_func()`. The fall-through path
429
-                                        // lowers the call as a scalar then treats the result as
430
-                                        // a source descriptor — `load %x from non-pointer f32`
431
-                                        // in the IR verifier, or afs_assign_allocatable with the
432
-                                        // scalar value in the wrong arg register at runtime
433
-                                        // (stdlib's pinv_s_operator hit this on the
434
-                                        // `pinva = ieee_value(1.0, NaN)` error path). Route
435
-                                        // through lower_array_assign so its bulk-fill plan
436
-                                        // applies. Skip when args contain array refs (the
437
-                                        // call really is producing an array result that other
438
-                                        // arms above already handle) or when the callee is an
439
-                                        // alloc-return user function (handled below).
440
-                                        let callee_is_scalar_broadcast = local_is_array_like(&info)
426
+                                        // Scalar-returning intrinsic broadcast to a whole array:
427
+                                        // `x = ieee_value(1.0, NaN)`, `x = epsilon(1.0)`,
428
+                                        // `x = huge(1.0)`. The fall-through path lowers the
429
+                                        // call as a scalar then treats the result as a source
430
+                                        // descriptor pointer — IR verifier catches "load from
431
+                                        // non-pointer fN" on fixed-size dests, and SEGV inside
432
+                                        // afs_assign_allocatable on descriptor-backed dests
433
+                                        // (stdlib's pinv_s_operator on the linalg-error path
434
+                                        // `pinva = ieee_value(1.0_sp, ieee_quiet_nan)`).
435
+                                        // Restricted to a known set of always-scalar
436
+                                        // intrinsics — extending it broadly mis-routes user
437
+                                        // functions that legitimately return arrays.
438
+                                        let callee_is_scalar_broadcast_intrinsic =
439
+                                            local_is_array_like(&info)
441440
                                                 && !callee_is_local_array
442441
                                                 && !callee_is_elemental_array_intrinsic
443442
                                                 && !callee_is_transformational_intrinsic
444
-                                            && call_args.iter().all(|arg| {
445
-                                                if let crate::ast::expr::SectionSubscript::Element(e)
446
-                                                    = &arg.value
447
-                                                {
448
-                                                    !expr_contains_array_refs(e, &ctx.locals)
449
-                                                } else {
450
-                                                    false
451
-                                                }
452
-                                            })
453443
                                                 && {
454444
                                                     if let Expr::Name { name: cname } = &callee.node {
455445
                                                         let lk = cname.to_lowercase();
456
-                                                    !ctx.alloc_return_funcs.contains(&lk)
446
+                                                        matches!(
447
+                                                            lk.as_str(),
448
+                                                            "ieee_value"
449
+                                                                | "epsilon"
450
+                                                                | "huge"
451
+                                                                | "tiny"
452
+                                                                | "radix"
453
+                                                                | "digits"
454
+                                                                | "precision"
455
+                                                                | "range"
456
+                                                                | "minexponent"
457
+                                                                | "maxexponent"
458
+                                                        )
457459
                                                     } else {
458460
                                                         false
459461
                                                     }
@@ -461,7 +463,7 @@ pub(crate) fn lower_stmt(b: &mut FuncBuilder, ctx: &mut LowerCtx, stmt: &Spanned
461463
                                         if callee_is_local_array
462464
                                             || callee_is_elemental_array_intrinsic
463465
                                             || callee_is_transformational_intrinsic
464
-                                            || callee_is_scalar_broadcast
466
+                                            || callee_is_scalar_broadcast_intrinsic
465467
                                         {
466468
                                             lower_array_assign(b, ctx, name, &info, value);
467469
                                             return;