[llvm] r305608 - bpf: fix a strict-aliasing issue

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 16:28:04 PDT 2017


Author: yhs
Date: Fri Jun 16 18:28:04 2017
New Revision: 305608

URL: http://llvm.org/viewvc/llvm-project?rev=305608&view=rev
Log:
bpf: fix a strict-aliasing issue

Davide Italiano reported the following issue if llvm
is compiled with gcc -Wstrict-aliasing -Werror:
.....
lib/Target/BPF/CMakeFiles/LLVMBPFCodeGen.dir/BPFISelDAGToDAG.cpp.o
../lib/Target/BPF/BPFISelDAGToDAG.cpp: In member function ‘virtual
void {anonymous}::BPFDAGToDAGISel::PreprocessISelDAG()’:
../lib/Target/BPF/BPFISelDAGToDAG.cpp:264:26: warning: dereferencing
type-punned pointer will break strict-aliasing rules
[-Wstrict-aliasing]
       val = *(uint16_t *)new_val;
.....

The error is caused by my previous commit (revision 305560).

This patch fixed the issue by introducing an union to avoid
type casting.

Signed-off-by: Yonghong Song <yhs at fb.com>

Modified:
    llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp?rev=305608&r1=305607&r2=305608&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp Fri Jun 16 18:28:04 2017
@@ -214,7 +214,12 @@ void BPFDAGToDAGISel::PreprocessISelDAG(
     if (Opcode != ISD::LOAD)
       continue;
 
-    unsigned char new_val[8]; // hold up the constant values replacing loads.
+    union {
+      uint8_t c[8];
+      uint16_t s;
+      uint32_t i;
+      uint64_t d;
+    } new_val; // hold up the constant values replacing loads.
     bool to_replace = false;
     SDLoc DL(Node);
     const LoadSDNode *LD = cast<LoadSDNode>(Node);
@@ -242,7 +247,7 @@ void BPFDAGToDAGISel::PreprocessISelDAG(
       const ConstantSDNode *CDN = dyn_cast<ConstantSDNode>(OP2.getNode());
       if (GADN && CDN)
         to_replace =
-            getConstantFieldValue(GADN, CDN->getZExtValue(), size, new_val);
+            getConstantFieldValue(GADN, CDN->getZExtValue(), size, new_val.c);
     } else if (LDAddrNode->getOpcode() > ISD::BUILTIN_OP_END &&
                LDAddrNode->getNumOperands() > 0) {
       DEBUG(dbgs() << "Check candidate load: "; LD->dump(); dbgs() << '\n');
@@ -250,7 +255,7 @@ void BPFDAGToDAGISel::PreprocessISelDAG(
       SDValue OP1 = LDAddrNode->getOperand(0);
       if (const GlobalAddressSDNode *GADN =
               dyn_cast<GlobalAddressSDNode>(OP1.getNode()))
-        to_replace = getConstantFieldValue(GADN, 0, size, new_val);
+        to_replace = getConstantFieldValue(GADN, 0, size, new_val.c);
     }
 
     if (!to_replace)
@@ -259,13 +264,13 @@ void BPFDAGToDAGISel::PreprocessISelDAG(
     // replacing the old with a new value
     uint64_t val;
     if (size == 1)
-      val = *(uint8_t *)new_val;
+      val = new_val.c[0];
     else if (size == 2)
-      val = *(uint16_t *)new_val;
+      val = new_val.s;
     else if (size == 4)
-      val = *(uint32_t *)new_val;
+      val = new_val.i;
     else {
-      val = *(uint64_t *)new_val;
+      val = new_val.d;
     }
 
     DEBUG(dbgs() << "Replacing load of size " << size << " with constant "
@@ -318,14 +323,17 @@ bool BPFDAGToDAGISel::getConstantFieldVa
   }
 
   // test whether host endianness matches target
-  uint8_t test_buf[2];
+  union {
+    uint8_t c[2];
+    uint16_t s;
+  } test_buf;
   uint16_t test_val = 0x2345;
   if (DL.isLittleEndian())
-    support::endian::write16le(test_buf, test_val);
+    support::endian::write16le(test_buf.c, test_val);
   else
-    support::endian::write16be(test_buf, test_val);
+    support::endian::write16be(test_buf.c, test_val);
 
-  bool endian_match = *(uint16_t *)test_buf == test_val;
+  bool endian_match = test_buf.s == test_val;
   for (uint64_t i = Offset, j = 0; i < Offset + Size; i++, j++)
     ByteSeq[j] = endian_match ? TmpVal[i] : TmpVal[Offset + Size - 1 - j];
 




More information about the llvm-commits mailing list