Skip to content

Safety guarantees regarding code motion? #252

Open
@mqudsi

Description

@mqudsi

Hi team,

I'm working with the rust-lang team on a concern that would overlap with cpu_features, and am specifically here because this project has been around for a long time, is well regarded, and looks to be very mature and well-designed!

My question is fairly simple - have you run into any issues due to a combination of inlined functions and code motion? Are there any steps the project itself takes or any guarantees that make you feel sufficiently confident that compiler optimizations can't cause instructions to be reordered out of the confines of the protective if statement?

For example, if you had the following contrived code sample:

#include "cpuinfo_x86.h"

static const X86Features features = GetX86Info().features;

void Compute(int m, int n) {
  int x, y;
  if (features.bmi2) {
    x = _bzhi_u32(m, n);
    y = x + 1;
  } else {
    y = m + n;
  }

  printf("%d\n", y);
}

Is there anything to prevent a (smart but not too smart) optimizing compiler from noticing that 1) _bzhi_u32() is a known, inlinable function with zero observable side effects, 2) x may be calculated without affecting the else branch, 3) features.bmi2 is always tested and changing the code to

void Compute(int m, int n) {
  ...
  bzhi x, m, n;
  incr x;
  add y, m, n;
  test features.bmi2;
  cmov y, x;
  ...
}

(or just keeping the jmp but calculating bzhi beforehand)

The project README doesn't mention that the burden is on a developer to make sure any code using the detected features in the if (features.foo) { ... } branch cannot be inlined to protect against code motion, so I'm wondering if there are any sections of the C or C++ specification or the GCC/LLVM internal APIs that document, e.g., code motion cannot happen across a non-inlined condition or anything else that would prevent a (compliant) compiler from generating code that possibly uses an unsupported instruction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions