Skip to content

GVN misunderstands aliasing, can create overlapping assignments #141038

Closed
@saethlin

Description

@saethlin

Reduced example from rustlantis, which is accepted by Miri without optimizations enabled:

#![feature(custom_mir, core_intrinsics)]

use std::intrinsics::mir::*;

#[custom_mir(dialect = "runtime")]
fn fn17() {
    mir!{
        let _17: Adt;
        let _33: *mut Adt;
        let _48: u32;
        let _73: &Adt;
        {
            _17 = Adt::Some(0);
            _33 = core::ptr::addr_of_mut!(_17);
            _73 = &(*_33);
            _48 = Field(Variant((*_73), 1), 0);
            (*_33) = Adt::Some(_48);
            Return()
        }
    }
}

fn main() {
    fn17();
}

enum Adt {
    None,
    Some(u32),
}

If I run this under Miri with -Zmir-enable-passes=+GVN, I see:

error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
  --> gvn-overlapping.rs:17:13
   |
17 |             (*_33) = Adt::Some(_48);
   |             ^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
   |
   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
   = note: BACKTRACE:
   = note: inside `fn17` at gvn-overlapping.rs:17:13: 17:36

The MIR diff for GVN is:

-// MIR for `fn17` before GVN
+// MIR for `fn17` after GVN
 
 fn fn17() -> () {
     let mut _0: ();
@@ -8,11 +8,15 @@ fn fn17() -> () {
     let mut _4: &Adt;
 
     bb0: {
-        _1 = Adt::Some(const 0_u32);
+        _1 = const Adt::Some(0_u32);
         _2 = &raw mut _1;
         _4 = &(*_2);
         _3 = copy (((*_4) as variant#1).0: u32);
-        (*_2) = Adt::Some(copy _3);
+        (*_2) = copy (*_4);
         return;
     }
 }
+
+alloc1 (size: 8, align: 4) {
+    01 00 00 00 00 00 00 00                         │ ........
+}

Metadata

Metadata

Assignees

Labels

A-mir-optArea: MIR optimizationsA-mir-opt-GVNArea: MIR opt Global Value Numbering (GVN)A-rustlantisA miscompilation found by RustlantisC-bugCategory: This is a bug.I-miscompileIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions