Merge commit c80c09f3e380 from llvm-project (by Dimitry Andric):

[CalcSpillWeights] Avoid x87 excess precision influencing weight result

  Fixes #99396

  The result of `VirtRegAuxInfo::weightCalcHelper` can be influenced by
  x87 excess precision, which can result in slightly different register
  choices when the compiler is hosted on x86_64 or i386. This leads to
  different object file output when cross-compiling to i386, or native.

  Similar to 7af3432e22b0, we need to add a `volatile` qualifier to the
  local `Weight` variable to force it onto the stack, and avoid the excess
  precision. Define `stack_float_t` in `MathExtras.h` for this purpose,
  and use it.

This is the version of the fix for PR276961 that landed upstream.

PR:		276961
Reported by:	cperciva
MFC after:	3 days
This commit is contained in:
Dimitry Andric 2024-07-28 13:13:37 +02:00
parent 52552d7572
commit 1a4b8325f6
2 changed files with 14 additions and 5 deletions

View File

@ -644,6 +644,14 @@ std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
return UX > (static_cast<U>(std::numeric_limits<T>::max())) / UY;
}
/// Type to force float point values onto the stack, so that x86 doesn't add
/// hidden precision, avoiding rounding differences on various platforms.
#if defined(__i386__) || defined(_M_IX86)
using stack_float_t = volatile float;
#else
using stack_float_t = float;
#endif
} // End llvm namespace
#endif

View File

@ -22,6 +22,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <tuple>
@ -256,7 +257,9 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
return -1.0f;
}
float Weight = 1.0f;
// Force Weight onto the stack so that x86 doesn't add hidden precision,
// similar to HWeight below.
stack_float_t Weight = 1.0f;
if (IsSpillable) {
// Get loop info for mi.
if (MI->getParent() != MBB) {
@ -283,11 +286,9 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
if (!HintReg)
continue;
// Force hweight onto the stack so that x86 doesn't add hidden precision,
// Force HWeight onto the stack so that x86 doesn't add hidden precision,
// making the comparison incorrectly pass (i.e., 1 > 1 == true??).
//
// FIXME: we probably shouldn't use floats at all.
volatile float HWeight = Hint[HintReg] += Weight;
stack_float_t HWeight = Hint[HintReg] += Weight;
if (HintReg.isVirtual() || MRI.isAllocatable(HintReg))
CopyHints.insert(CopyHint(HintReg, HWeight));
}