[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c
Chris Lattner
lattner at cs.uiuc.edu
Fri Jul 15 19:14:19 PDT 2005
Changes in directory llvm-gcc/gcc:
llvm-expand.c updated: 1.103 -> 1.104
---
Log message:
Fix PR594: http://llvm.cs.uiuc.edu/PR594 , a really nasty miscompilation of bitfields on big-endian targets
like PPC and sparc.
---
Diffs of the changes: (+19 -6)
llvm-expand.c | 25 +++++++++++++++++++------
1 files changed, 19 insertions(+), 6 deletions(-)
Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.103 llvm-gcc/gcc/llvm-expand.c:1.104
--- llvm-gcc/gcc/llvm-expand.c:1.103 Thu Jul 7 12:32:46 2005
+++ llvm-gcc/gcc/llvm-expand.c Fri Jul 15 21:14:08 2005
@@ -2858,6 +2858,13 @@
llvm_value *Idx;
if (BitSize == 0) return Src; /* Not a bitfield reference */
+
+ /* If this target has bitfields laid out in big-endian order, invert the bit
+ * in the word if needed.
+ */
+ if (BITS_BIG_ENDIAN)
+ BitStart = ValSize-BitStart-BitSize;
+
if (BitStart+BitSize != ValSize) {
Idx = llvm_constant_new_integral(UByteTy, ValSize-(BitStart+BitSize));
Src = append_inst(Fn, create_binary_inst("tmp", O_Shl, Src, Idx));
@@ -2872,15 +2879,23 @@
unsigned BitStart, unsigned BitSize,
int isVolatile) {
llvm_value *OldVal;
- llvm_type *ResultType;
+ llvm_type *ResultType = GET_POINTER_TYPE_ELEMENT(Ptr->Ty);
+ unsigned ResultTypeSizeInBits = llvm_type_get_size(ResultType)*8;
/* Get a mask of all ones of the right size */
long long Mask = (1LL << BitSize)-1;
- /* Shift it over to the right place. */
- Mask <<= BitStart;
if (BitSize == 0) return Src;
+ /* If this target has bitfields laid out in big-endian order, invert the bit
+ * in the word if needed.
+ */
+ if (BITS_BIG_ENDIAN)
+ BitStart = ResultTypeSizeInBits-BitStart-BitSize;
+
+ /* Shift it over to the right place. */
+ Mask <<= BitStart;
+
/* If we are not storing starting at the zero'th bit, emit a shift of the
* computed value.
*/
@@ -2889,10 +2904,8 @@
Src = append_inst(Fn, create_binary_inst("tmp", O_Shl, Src, Idx));
}
- ResultType = GET_POINTER_TYPE_ELEMENT(Ptr->Ty);
-
/* Mask off any upper bits of the value we computed, but don't want. */
- if (BitStart + BitSize != llvm_type_get_size(ResultType)) {
+ if (BitStart + BitSize != ResultTypeSizeInBits) {
/* Make an LLVM value for the constant. */
llvm_value *MaskVal = llvm_constant_new_integral(ResultType, Mask);
Src = append_inst(Fn, create_binary_inst("tmp", O_And, Src, MaskVal));
More information about the llvm-commits
mailing list