[AArch64] Mark function calls as possibly changing FPCR
authorSerge Pavlov <sepavloff@gmail.com>
Mon, 30 Jan 2023 12:49:57 +0000 (19:49 +0700)
committerSerge Pavlov <sepavloff@gmail.com>
Wed, 1 Feb 2023 05:06:51 +0000 (12:06 +0700)
This patch does the same changes as D111433 for PowerPC and D139549 for
X86, - in the strictfp function all calls are marked as implicit defs of
FPCR. It prevents from moving FP operations across function calls, which
may change rounding mode, as fesetround does.

Differential Revision: https://reviews.llvm.org/D143001

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.h
llvm/test/CodeGen/AArch64/strict-fp-func.ll [new file with mode: 0644]

index ca6f1aa..72e99b3 100644 (file)
@@ -14946,6 +14946,11 @@ AArch64TargetLowering::getScratchRegisters(CallingConv::ID) const {
   return ScratchRegs;
 }
 
+const MCPhysReg *AArch64TargetLowering::getRoundingControlRegisters() const {
+  static const MCPhysReg RCRegs[] = {AArch64::FPCR, 0};
+  return RCRegs;
+}
+
 bool
 AArch64TargetLowering::isDesirableToCommuteWithShift(const SDNode *N,
                                                      CombineLevel Level) const {
index 92619f7..7544a0c 100644 (file)
@@ -670,6 +670,7 @@ public:
                                      CodeGenOpt::Level OptLevel) const override;
 
   const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
+  const MCPhysReg *getRoundingControlRegisters() const override;
 
   /// Returns false if N is a bit extraction pattern of (X >> C) & Mask.
   bool isDesirableToCommuteWithShift(const SDNode *N,
diff --git a/llvm/test/CodeGen/AArch64/strict-fp-func.ll b/llvm/test/CodeGen/AArch64/strict-fp-func.ll
new file mode 100644 (file)
index 0000000..198d4fd
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llc -mtriple aarch64-none-linux-gnu -stop-after=finalize-isel %s -o - | FileCheck %s
+
+define float @func_02(float %x, float %y) strictfp nounwind {
+  %call = call float @func_01(float %x) strictfp
+  %res = call float @llvm.experimental.constrained.fadd.f32(float %call, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore") strictfp
+  ret float %res
+}
+; CHECK-LABEL: name: func_02
+; CHECK:       BL @func_01, {{.*}}, implicit-def $fpcr
+
+
+declare float @func_01(float)
+declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)