Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llvm-gcc4 crashes on this bitfield reference #1278

Closed
lattner opened this issue Sep 12, 2006 · 2 comments
Closed

llvm-gcc4 crashes on this bitfield reference #1278

lattner opened this issue Sep 12, 2006 · 2 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla code-quality compile-fail Use [accepts-invalid] and [rejects-valid] instead llvm-tools All llvm tools that do not have corresponding tag

Comments

@lattner
Copy link
Collaborator

lattner commented Sep 12, 2006

Bugzilla Link 906
Resolution FIXED
Resolved on Feb 22, 2010 12:48
Version 1.7
OS All

Extended Description

struct state_struct {
  unsigned long long phys_frame: 50;
  unsigned valid : 2;
} s;

int mem_access(struct state_struct *p) {
  return p->valid;
}

@lattner
Copy link
Collaborator Author

lattner commented Sep 12, 2006

assigned to @lattner

@lattner
Copy link
Collaborator Author

lattner commented Sep 12, 2006

Fixed.  Testcase here:
Regression/CFrontend/2006-09-11-BitfieldRefCrash.c

Patch here:

Index: llvm-convert.cpp

====
--- llvm-convert.cpp    (revision 117816)
+++ llvm-convert.cpp    (working copy)
@@ -3704,6 +3704,9 @@
   }
 
   if (tree DeclaredType = DECL_BIT_FIELD_TYPE(FieldDecl)) {
+    const Type LLVMFieldTy = 
+      cast(FieldPtr->getType())->getElementType();
+    
     // If this is a bitfield, the declared type must be an integral type.
     FieldTy = ConvertType(DeclaredType);
     // If the field result is a bool, cast to a ubyte instead.  It is not
@@ -3713,11 +3716,20 @@
       FieldTy = Type::UByteTy;
     assert(FieldTy->isInteger() && "Invalid bitfield");
 
+    // If the LLVM notion of the field type is larger than the actual field type
+    // being accessed, use the LLVM type.  This avoids pointer casts and other
+    // bad things that are difficult to clean up later.  This occurs in cases
+    // like "struct X{ unsigned long long x:50; unsigned y:2; }" when accessing
+    // y.  We want to access the field as a ulong, not as a uint with an offset.
+    if (LLVMFieldTy->isInteger() &&
+        LLVMFieldTy->getPrimitiveSize() > FieldTy->getPrimitiveSize())
+      FieldTy = LLVMFieldTy;
+    
     // We are now loading/storing through a casted pointer type, whose 
     // signedness depends on the signedness of the field.  Force the field to 
     // be unsigned.  This solves performance problems where you have, for 
     // example:  struct { int A:1; unsigned B:2; };  Consider a store to A then
-    // a store to be.  In this case, without this conversion, you'd have a 
+    // a store to B.  In this case, without this conversion, you'd have a 
     // store through an int
, followed by a load from a uint*.  Forcing them
     // both to uint* allows the store to be forwarded to the load.
     FieldTy = FieldTy->getUnsignedVersion();

-Chris

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
jeanPerier pushed a commit to jeanPerier/llvm-project that referenced this issue Jan 4, 2022
Add cast to avoid type mismatch errors on multiply op.
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla code-quality compile-fail Use [accepts-invalid] and [rejects-valid] instead llvm-tools All llvm tools that do not have corresponding tag
Projects
None yet
Development

No branches or pull requests

1 participant