diff options
Diffstat (limited to 'tests/codegen-llvm/asm/critical.rs')
| -rw-r--r-- | tests/codegen-llvm/asm/critical.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/tests/codegen-llvm/asm/critical.rs b/tests/codegen-llvm/asm/critical.rs new file mode 100644 index 00000000000..0f29d7c69b4 --- /dev/null +++ b/tests/codegen-llvm/asm/critical.rs @@ -0,0 +1,36 @@ +//@ only-x86_64 +//@ compile-flags: -C no-prepopulate-passes +#![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 +} |
