//@ only-x86_64 //@ compile-flags: -C no-prepopulate-passes #![feature(asm_goto)] #![feature(asm_goto_with_outputs)] #![crate_type = "lib"] use std::arch::asm; // Regression test for #137867. Check that critical edges have been split before code generation, // and so all stores to the asm output occur on disjoint paths without any of them jumping to // another callbr label. // // CHECK-LABEL: @f( // CHECK: [[OUT:%.*]] = callbr i32 asm // CHECK-NEXT: to label %[[BB0:.*]] [label %[[BB1:.*]], label %[[BB2:.*]]], // CHECK: [[BB1]]: // CHECK-NEXT: store i32 [[OUT]], ptr %a // CHECK-NEXT: br label %[[BBR:.*]] // CHECK: [[BB2]]: // CHECK-NEXT: store i32 [[OUT]], ptr %a // CHECK-NEXT: br label %[[BBR]] // CHECK: [[BB0]]: // CHECK-NEXT: store i32 [[OUT]], ptr %a // CHECK-NEXT: br label %[[BBR]] // CHECK: [[BBR]]: // CHECK-NEXT: [[RET:%.*]] = load i32, ptr %a // CHECK-NEXT: ret i32 [[RET]] #[unsafe(no_mangle)] pub unsafe fn f(mut a: u32) -> u32 { asm!( "jmp {} jmp {}", label {}, label {}, inout("eax") a, ); a }