David Green 888f84f72c
[ARM] Return the correct chain when expanding READ_REGISTER (#145237)
This prevents it CSEing multiple nodes together from "volatile"
registers as they would end up with the same chain. The new chain out
should be the chain from the new READ_REGISTER node.

Fixes #144845
2025-06-25 07:08:46 +01:00

125 lines
3.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple=arm-none-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s --check-prefix=ARM --check-prefix=ACORE
; RUN: llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=ARM --check-prefix=MCORE
define i32 @read_i32_encoded_register() nounwind {
; ARM-LABEL: read_i32_encoded_register:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: mrc p1, #2, r0, c3, c4, #5
; ARM-NEXT: bx lr
entry:
%reg = call i32 @llvm.read_register.i32(metadata !0)
ret i32 %reg
}
define i64 @read_i64_encoded_register() nounwind {
; ARM-LABEL: read_i64_encoded_register:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: mrrc p1, #2, r0, r1, c3
; ARM-NEXT: bx lr
entry:
%reg = call i64 @llvm.read_register.i64(metadata !1)
ret i64 %reg
}
define i64 @read_volatile_i64_twice() {
; ACORE-LABEL: read_volatile_i64_twice:
; ACORE: @ %bb.0: @ %entry
; ACORE-NEXT: mrrc p15, #1, r0, r1, c14
; ACORE-NEXT: mrrc p15, #1, r2, r3, c14
; ACORE-NEXT: eor r0, r2, r0
; ACORE-NEXT: eor r1, r3, r1
; ACORE-NEXT: bx lr
;
; MCORE-LABEL: read_volatile_i64_twice:
; MCORE: @ %bb.0: @ %entry
; MCORE-NEXT: mrrc p15, #1, r0, r1, c14
; MCORE-NEXT: mrrc p15, #1, r2, r3, c14
; MCORE-NEXT: eors r0, r2
; MCORE-NEXT: eors r1, r3
; MCORE-NEXT: bx lr
entry:
%0 = tail call i64 @llvm.read_volatile_register.i64(metadata !5)
%1 = tail call i64 @llvm.read_volatile_register.i64(metadata !5)
%xor = xor i64 %1, %0
ret i64 %xor
}
define i32 @read_apsr() nounwind {
; ARM-LABEL: read_apsr:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: mrs r0, apsr
; ARM-NEXT: bx lr
entry:
%reg = call i32 @llvm.read_register.i32(metadata !2)
ret i32 %reg
}
define i32 @read_fpscr() nounwind {
; ARM-LABEL: read_fpscr:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: vmrs r0, fpscr
; ARM-NEXT: bx lr
entry:
%reg = call i32 @llvm.read_register.i32(metadata !3)
ret i32 %reg
}
define void @write_i32_encoded_register(i32 %x) nounwind {
; ARM-LABEL: write_i32_encoded_register:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: mcr p1, #2, r0, c3, c4, #5
; ARM-NEXT: bx lr
entry:
call void @llvm.write_register.i32(metadata !0, i32 %x)
ret void
}
define void @write_i64_encoded_register(i64 %x) nounwind {
; ARM-LABEL: write_i64_encoded_register:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: mcrr p1, #2, r0, r1, c3
; ARM-NEXT: bx lr
entry:
call void @llvm.write_register.i64(metadata !1, i64 %x)
ret void
}
define void @write_apsr(i32 %x) nounwind {
; ACORE-LABEL: write_apsr:
; ACORE: @ %bb.0: @ %entry
; ACORE-NEXT: msr APSR_nzcvq, r0
; ACORE-NEXT: bx lr
;
; MCORE-LABEL: write_apsr:
; MCORE: @ %bb.0: @ %entry
; MCORE-NEXT: msr apsr_nzcvq, r0
; MCORE-NEXT: bx lr
entry:
call void @llvm.write_register.i32(metadata !4, i32 %x)
ret void
}
define void @write_fpscr(i32 %x) nounwind {
; ARM-LABEL: write_fpscr:
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: vmsr fpscr, r0
; ARM-NEXT: bx lr
entry:
call void @llvm.write_register.i32(metadata !3, i32 %x)
ret void
}
declare i32 @llvm.read_register.i32(metadata) nounwind
declare i64 @llvm.read_register.i64(metadata) nounwind
declare void @llvm.write_register.i32(metadata, i32) nounwind
declare void @llvm.write_register.i64(metadata, i64) nounwind
!0 = !{!"cp1:2:c3:c4:5"}
!1 = !{!"cp1:2:c3"}
!2 = !{!"apsr"}
!3 = !{!"fpscr"}
!4 = !{!"apsr_nzcvq"}
!5 = !{!"cp15:1:c14"}