[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