[dragonegg] r181883 - Fix PR15984: add support for loading from bitfields with a non-integer (but

Duncan Sands baldrick at free.fr
Wed May 15 06:28:54 PDT 2013


Author: baldrick
Date: Wed May 15 08:28:53 2013
New Revision: 181883

URL: http://llvm.org/viewvc/llvm-project?rev=181883&view=rev
Log:
Fix PR15984: add support for loading from bitfields with a non-integer (but
scalar) type.

Added:
    dragonegg/trunk/test/compilator/local/ada/pr15984.adb
    dragonegg/trunk/test/compilator/local/ada/pr15984.ads
Modified:
    dragonegg/trunk/src/Convert.cpp

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=181883&r1=181882&r2=181883&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Wed May 15 08:28:53 2013
@@ -2849,9 +2849,29 @@ Value *TreeToLLVM::EmitLoadOfLValue(tree
     Val = isSigned ? Builder.CreateAShr(Val, ShAmt)
                    : Builder.CreateLShr(Val, ShAmt);
 
-    // Get the bits as a value of the correct type.
-    // FIXME: This assumes the result is an integer.
-    return Builder.CreateIntCast(Val, Ty, isSigned);
+    // If the result is an integer then cast to the right size and return.  This
+    // is an optimization: the code below would give the same result.
+    if (Ty->isIntegerTy())
+      return Builder.CreateIntCast(Val, Ty, isSigned);
+
+    // Otherwise the result type is a non-integer scalar, possibly a vector.
+    // Get the bits as an integer with the same alloc size as the result.
+    Type *ResIntTy = IntegerType::get(Context, DL.getTypeAllocSizeInBits(Ty));
+    Value *ResInt = Builder.CreateIntCast(Val, ResIntTy, isSigned);
+
+    // Create a temporary with the final type and store the bits to it.  Going
+    // via a temporary isn't really necessary: we could get the same effect by
+    // casting the value.  It is very natural however, since in effect we just
+    // displace the original set of bits to a new memory location that is byte
+    // aligned, from which we can trivially load the desired value.
+    unsigned Alignment = std::max(DL.getPrefTypeAlignment(Ty),
+                                  DL.getPrefTypeAlignment(ResIntTy));
+    Value *Tmp = CreateTemporary(Ty, Alignment);
+    Builder.CreateStore(ResInt,
+                        Builder.CreateBitCast(Tmp, ResIntTy->getPointerTo()));
+
+    // Load out the bits as the correct type.
+    return Builder.CreateLoad(Tmp);
   }
 }
 

Added: dragonegg/trunk/test/compilator/local/ada/pr15984.adb
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/compilator/local/ada/pr15984.adb?rev=181883&view=auto
==============================================================================
--- dragonegg/trunk/test/compilator/local/ada/pr15984.adb (added)
+++ dragonegg/trunk/test/compilator/local/ada/pr15984.adb Wed May 15 08:28:53 2013
@@ -0,0 +1,20 @@
+package body PR15984 is
+
+  AA : Type3;
+
+  procedure Startup is
+  begin -- Startup
+    AA.EEE := False;
+  end Startup;
+
+  procedure Set is
+  begin -- Set
+     AA.EEE := True;
+  end Set;
+
+  procedure Reset is
+  begin -- Reset
+     AA.EEE := False;
+  end Reset;
+
+end PR15984;

Added: dragonegg/trunk/test/compilator/local/ada/pr15984.ads
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/compilator/local/ada/pr15984.ads?rev=181883&view=auto
==============================================================================
--- dragonegg/trunk/test/compilator/local/ada/pr15984.ads (added)
+++ dragonegg/trunk/test/compilator/local/ada/pr15984.ads Wed May 15 08:28:53 2013
@@ -0,0 +1,27 @@
+package PR15984 is
+
+   type Type1 is (AAA, BBB);
+
+   type Type2 is record
+      CCC : Boolean;
+      DDD : Float;
+   end record;
+   pragma pack( Type2 );
+
+   type Type3 (Format : Type1 := AAA) is record
+      case Format is
+   	 when AAA  =>	
+   	    EEE : Boolean;
+   	 when BBB  =>
+   	    FFF : Type2;
+      end case;
+   end record;
+   pragma PACK (Type3);
+
+   procedure Startup;
+
+   procedure Set;
+
+   procedure Reset;
+
+end PR15984;





More information about the llvm-commits mailing list