[cfe-commits] r51224 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGen/bool-bitfield.c

Eli Friedman eli.friedman at gmail.com
Sat May 17 13:03:47 PDT 2008


Author: efriedma
Date: Sat May 17 15:03:47 2008
New Revision: 51224

URL: http://llvm.org/viewvc/llvm-project?rev=51224&view=rev
Log:
Fix support for _Bool bitfields. The issue is that the bitfield width 
used for _Bool is not the same as the primitive width (which for _Bool 
is 1 bit).  The load and store changes add some casts to make the 
types consistent.  The EmitLValue changes make sure that the pointer is 
of an appropriate type for loading the bitfield.

This isn't perfect, but it's an improvement, and getting everything 
right depends on actually laying out structs in an ABI-compliant way.


Added:
    cfe/trunk/test/CodeGen/bool-bitfield.c
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=51224&r1=51223&r2=51224&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat May 17 15:03:47 2008
@@ -14,11 +14,13 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/AST.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -175,6 +177,11 @@
   V = LV.isBitfieldSigned() ?
     Builder.CreateAShr(V, ShAmt, "tmp") :
     Builder.CreateLShr(V, ShAmt, "tmp");
+
+  // The bitfield type and the normal type differ when the storage sizes
+  // differ (currently just _Bool).
+  V = Builder.CreateIntCast(V, ConvertType(ExprType), false, "tmp");
+
   return RValue::get(V);
 }
 
@@ -280,13 +287,18 @@
   unsigned short StartBit = Dst.getBitfieldStartBit();
   unsigned short BitfieldSize = Dst.getBitfieldSize();
   llvm::Value *Ptr = Dst.getBitfieldAddr();
-  const llvm::Type *EltTy =
-    cast<llvm::PointerType>(Ptr->getType())->getElementType();
-  unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
 
   llvm::Value *NewVal = Src.getScalarVal();
   llvm::Value *OldVal = Builder.CreateLoad(Ptr, "tmp");
 
+  // The bitfield type and the normal type differ when the storage sizes
+  // differ (currently just _Bool).
+  const llvm::Type *EltTy = OldVal->getType();
+  unsigned EltTySize = CGM.getTargetData().getABITypeSizeInBits(EltTy);
+
+  NewVal = Builder.CreateIntCast(NewVal, EltTy, false, "tmp");
+
+  // Move the bits into the appropriate location
   llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, StartBit);
   NewVal = Builder.CreateShl(NewVal, ShAmt, "tmp");
 
@@ -531,7 +543,11 @@
   if (!Field->isBitField()) {
     V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
   } else {
-    const llvm::Type *FieldTy = ConvertType(Field->getType());
+    // FIXME: CodeGenTypes should expose a method to get the appropriate
+    // type for FieldTy (the appropriate type is ABI-dependent).
+    unsigned EltTySize =
+      CGM.getTargetData().getABITypeSizeInBits(ConvertType(Field->getType()));
+    const llvm::Type *FieldTy = llvm::IntegerType::get(EltTySize);
     const llvm::PointerType *BaseTy =
       cast<llvm::PointerType>(BaseValue->getType());
     unsigned AS = BaseTy->getAddressSpace();

Added: cfe/trunk/test/CodeGen/bool-bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bool-bitfield.c?rev=51224&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/bool-bitfield.c (added)
+++ cfe/trunk/test/CodeGen/bool-bitfield.c Sat May 17 15:03:47 2008
@@ -0,0 +1,54 @@
+// RUN: clang -emit-llvm %s
+
+// From GCC PR19331
+struct SysParams
+{
+ unsigned short tag;
+ unsigned short version;
+ unsigned int seqnum;
+ int contrast;
+ int igain_1, igain_2;
+ int oattn_1, oattn_2;
+ int max_out_vltg_1, max_out_vltg_2;
+ int max_mains_current;
+ int meters_mode;
+ int input_select;
+ _Bool input_parallelch2:1;
+ _Bool cliplmt_ch1:1;
+ _Bool cliplmt_ch2:1;
+ _Bool gate_ch1:1;
+ _Bool gate_ch2:1;
+ _Bool mute_ch1:1;
+ _Bool mute_ch2:1;
+ _Bool brownout:1;
+ _Bool power_on:1;
+ _Bool pwrup_mute:1;
+ _Bool keylock:1;
+ _Bool dsp_ch1:1;
+ _Bool dsp_ch2:1;
+ int dsp_preset;
+ long unlock_code;
+};
+extern struct SysParams params;
+
+void foo(void *);
+void kcmd_setParams(void)
+{
+ struct {
+  unsigned char igain_1;
+  unsigned char igain_2;
+  unsigned char max_out_vltg_1;
+  unsigned char max_out_vltg_2;
+  unsigned char max_imains;
+  unsigned char cliplmt_ch1:1;
+  unsigned char cliplmt_ch2:1;
+  unsigned char gate_ch1:1;
+  unsigned char gate_ch2:1;
+ } msg;
+ foo(&msg);
+ params.cliplmt_ch1 = msg.cliplmt_ch1;
+ params.cliplmt_ch2 = msg.cliplmt_ch2;
+ params.gate_ch1 = msg.gate_ch1;
+ params.gate_ch2 = msg.gate_ch2;
+}
+





More information about the cfe-commits mailing list