[llvm-commits] [dragonegg] r153405 - in /dragonegg/trunk: src/Convert.cpp test/validator/c++/2012-03-25-LoadRange.cpp
Duncan Sands
baldrick at free.fr
Sat Mar 24 22:52:06 PDT 2012
Author: baldrick
Date: Sun Mar 25 00:52:05 2012
New Revision: 153405
URL: http://llvm.org/viewvc/llvm-project?rev=153405&view=rev
Log:
When loading an integer type with precision less than its size (eg a C++ bool),
annotate the load with metadata describing the range of possible values loaded.
Added:
dragonegg/trunk/test/validator/c++/2012-03-25-LoadRange.cpp
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=153405&r1=153404&r2=153405&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Sun Mar 25 00:52:05 2012
@@ -285,6 +285,30 @@
llvm_unreachable("Don't know how to turn this into memory!");
}
+/// describeTypeRange - Given two integer types, return metadata describing the
+/// set obtained by extending all values of the smaller type to the larger.
+static MDNode *describeTypeRange(Type *SmallTy, Type *LargeTy, bool isSigned) {
+ assert(isa<IntegerType>(SmallTy) && isa<IntegerType>(LargeTy) &&
+ "Expected integer types!");
+ unsigned ActiveBits = SmallTy->getIntegerBitWidth();
+ unsigned TotalBits = LargeTy->getIntegerBitWidth();
+ assert(ActiveBits < TotalBits && "Full range not allowed!");
+ assert(ActiveBits > 0 && "Empty range not allowed!");
+ APInt First, Last;
+ if (isSigned) {
+ Last = APInt::getOneBitSet(TotalBits, ActiveBits - 1);
+ First = -Last;
+ } else {
+ First = APInt::getNullValue(TotalBits);
+ Last = APInt::getOneBitSet(TotalBits, ActiveBits);
+ }
+
+ Value *Range[2] = {
+ ConstantInt::get(LargeTy, First), ConstantInt::get(LargeTy, Last)
+ };
+ return MDNode::get(Context, Range);
+}
+
/// isDirectMemoryAccessSafe - Whether directly storing/loading a value of the
/// given register type generates the correct in-memory representation for the
/// type. Eg, if a 32 bit wide integer type has only one bit of precision then
@@ -369,6 +393,8 @@
unsigned Size = GET_MODE_BITSIZE(TYPE_MODE(type));
Type *MemTy = IntegerType::get(Context, Size);
LoadInst *LI = LoadFromLocation(Loc, MemTy, Builder);
+ MDNode *Range = describeTypeRange(RegTy, MemTy, !TYPE_UNSIGNED(type));
+ LI->setMetadata(LLVMContext::MD_range, Range);
return Builder.CreateTruncOrBitCast(LI, RegTy);
}
Added: dragonegg/trunk/test/validator/c++/2012-03-25-LoadRange.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/validator/c%2B%2B/2012-03-25-LoadRange.cpp?rev=153405&view=auto
==============================================================================
--- dragonegg/trunk/test/validator/c++/2012-03-25-LoadRange.cpp (added)
+++ dragonegg/trunk/test/validator/c++/2012-03-25-LoadRange.cpp Sun Mar 25 00:52:05 2012
@@ -0,0 +1,7 @@
+// RUN: %dragonegg -S -o - %s | FileCheck %s
+
+bool foo(bool *p) {
+ return *p;
+// CHECK: load i8* {{.*}} !range !0
+}
+// CHECK: !0 = metadata !{i8 0, i8 2}
More information about the llvm-commits
mailing list