[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