[clang] dac49e8 - [Arm] Fix generating code with UB in NeonEmitter (#121802)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 24 02:57:27 PST 2025


Author: Momchil Velikov
Date: 2025-01-24T10:57:23Z
New Revision: dac49e8ddd5dc0104c238f09cdd532e6fb5c4f1d

URL: https://github.com/llvm/llvm-project/commit/dac49e8ddd5dc0104c238f09cdd532e6fb5c4f1d
DIFF: https://github.com/llvm/llvm-project/commit/dac49e8ddd5dc0104c238f09cdd532e6fb5c4f1d.diff

LOG: [Arm] Fix generating code with UB in NeonEmitter (#121802)

When generating `arm_neon.h`, NeonEmitter outputs code that
violates strict aliasing rules (C23 6.5 Expressions #7,
C++23 7.2.1 Value category [basic.lval] #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`.

Added: 
    

Modified: 
    clang/utils/TableGen/NeonEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp
index d7d649dd2456d5..49633bb7b7f584 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -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);
 }


        


More information about the cfe-commits mailing list