llvm-project/llvm/test/CodeGen/AArch64/inline-asm-speculation.ll
Eli Friedman 1b39328d74
[CodeGen] Fix MachineInstr::isSafeToMove handling of inline asm. (#126807)
Even if an inline asm doesn't have memory effects, we can't assume it's
safe to speculate: it could trap, or cause undefined behavior. At the
LLVM IR level, this is handled correctly: we don't speculate inline asm
(unless it's marked "speculatable", but I don't think anyone does that).
Codegen also needs to respect this restriction.

This change stops Early If Conversion and similar passes from
speculating an INLINEASM MachineInstr.

Some uses of isSafeToMove probably could be switched to a different API:
isSafeToMove assumes you're hoisting, but we could handle some forms of
sinking more aggressively. But I'll leave that for a followup, if it
turns out to be relevant.

See also discussion on gcc bugtracker
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102150 .
2025-02-25 15:29:12 -08:00

39 lines
1.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
; Make sure we don't speculatively execute inline asm statements.
define dso_local i32 @main(i32 %argc, ptr %argv) {
; CHECK-LABEL: main:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: cmp w0, #3
; CHECK-NEXT: b.ne .LBB0_2
; CHECK-NEXT: // %bb.1: // %if.then
; CHECK-NEXT: //APP
; CHECK-NEXT: mrs x0, SPSR_EL2
; CHECK-NEXT: //NO_APP
; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NEXT: ret
; CHECK-NEXT: .LBB0_2: // %if.else
; CHECK-NEXT: //APP
; CHECK-NEXT: mrs x0, SPSR_EL1
; CHECK-NEXT: //NO_APP
; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NEXT: ret
entry:
%cmp = icmp eq i32 %argc, 3
br i1 %cmp, label %if.then, label %if.else
if.then:
%0 = tail call i64 asm "mrs $0, SPSR_EL2", "=r"()
br label %if.end
if.else:
%1 = tail call i64 asm "mrs $0, SPSR_EL1", "=r"()
br label %if.end
if.end:
%y.0.in = phi i64 [ %0, %if.then ], [ %1, %if.else ]
%y.0 = trunc i64 %y.0.in to i32
ret i32 %y.0
}