Skip to content

Commit

Permalink
[Arm] Fix generating code with UB in NeonEmitter (llvm#121802)
Browse files Browse the repository at this point in the history
When generating `arm_neon.h`, NeonEmitter outputs code that
violates strict aliasing rules (C23 6.5 Expressions rust-lang#7,
C++23 7.2.1 Value category [basic.lval] rust-lang#11), for example:

    bfloat16_t __reint = __p0;
    uint32_t __reint1 = (uint32_t)(*(uint16_t *) &__reint) << 16;
    __ret = *(float32_t *) &__reint1;

This patch fixed the offending code by replacing it with
a call to `__builtin_bit_cast`.
  • Loading branch information
momchil-velikov authored Jan 24, 2025
1 parent 8e70273 commit dac49e8
Showing 1 changed file with 3 additions and 17 deletions.
20 changes: 3 additions & 17 deletions clang/utils/TableGen/NeonEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1592,24 +1592,10 @@ Intrinsic::DagEmitter::emitDagCast(const DagInit *DI, bool IsBitCast) {
}

std::string S;
if (IsBitCast) {
// Emit a reinterpret cast. The second operand must be an lvalue, so create
// a temporary.
std::string N = "reint";
unsigned I = 0;
while (Intr.Variables.find(N) != Intr.Variables.end())
N = "reint" + utostr(++I);
Intr.Variables[N] = Variable(R.first, N + Intr.VariablePostfix);

Intr.OS << R.first.str() << " " << Intr.Variables[N].getName() << " = "
<< R.second << ";";
Intr.emitNewLine();

S = "*(" + castToType.str() + " *) &" + Intr.Variables[N].getName() + "";
} else {
// Emit a normal (static) cast.
if (IsBitCast)
S = "__builtin_bit_cast(" + castToType.str() + ", " + R.second + ")";
else
S = "(" + castToType.str() + ")(" + R.second + ")";
}

return std::make_pair(castToType, S);
}
Expand Down

0 comments on commit dac49e8

Please sign in to comment.