Skip to content

Commit dac49e8

Browse files
[Arm] Fix generating code with UB in NeonEmitter (llvm#121802)
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`.
1 parent 8e70273 commit dac49e8

File tree

1 file changed

+3
-17
lines changed

1 file changed

+3
-17
lines changed

clang/utils/TableGen/NeonEmitter.cpp

+3-17
Original file line numberDiff line numberDiff line change
@@ -1592,24 +1592,10 @@ Intrinsic::DagEmitter::emitDagCast(const DagInit *DI, bool IsBitCast) {
15921592
}
15931593

15941594
std::string S;
1595-
if (IsBitCast) {
1596-
// Emit a reinterpret cast. The second operand must be an lvalue, so create
1597-
// a temporary.
1598-
std::string N = "reint";
1599-
unsigned I = 0;
1600-
while (Intr.Variables.find(N) != Intr.Variables.end())
1601-
N = "reint" + utostr(++I);
1602-
Intr.Variables[N] = Variable(R.first, N + Intr.VariablePostfix);
1603-
1604-
Intr.OS << R.first.str() << " " << Intr.Variables[N].getName() << " = "
1605-
<< R.second << ";";
1606-
Intr.emitNewLine();
1607-
1608-
S = "*(" + castToType.str() + " *) &" + Intr.Variables[N].getName() + "";
1609-
} else {
1610-
// Emit a normal (static) cast.
1595+
if (IsBitCast)
1596+
S = "__builtin_bit_cast(" + castToType.str() + ", " + R.second + ")";
1597+
else
16111598
S = "(" + castToType.str() + ")(" + R.second + ")";
1612-
}
16131599

16141600
return std::make_pair(castToType, S);
16151601
}

0 commit comments

Comments
 (0)