[llvm-commits] [llvm] r142558 - in /llvm/trunk: lib/Analysis/ValueTracking.cpp test/Transforms/SimplifyLibCalls/StrLen.ll

Nick Lewycky nicholas at mxc.ca
Wed Oct 19 17:34:35 PDT 2011


Author: nicholas
Date: Wed Oct 19 19:34:35 2011
New Revision: 142558

URL: http://llvm.org/viewvc/llvm-project?rev=142558&view=rev
Log:
"@string = constant i8 0" is a value i8* string of length zero. Analyze that
correctly in GetStringLength, fixing PR11181!

Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/test/Transforms/SimplifyLibCalls/StrLen.ll

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=142558&r1=142557&r2=142558&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Wed Oct 19 19:34:35 2011
@@ -1525,8 +1525,7 @@
 /// null-terminated C string pointed to by V.  If successful, it returns true
 /// and returns the string in Str.  If unsuccessful, it returns false.
 bool llvm::GetConstantStringInfo(const Value *V, std::string &Str,
-                                 uint64_t Offset,
-                                 bool StopAtNul) {
+                                 uint64_t Offset, bool StopAtNul) {
   // If V is NULL then return false;
   if (V == NULL) return false;
 
@@ -1536,7 +1535,7 @@
   
   // If the value is not a GEP instruction nor a constant expression with a
   // GEP instruction, then return false because ConstantArray can't occur
-  // any other way
+  // any other way.
   const User *GEP = 0;
   if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
     GEP = GEPI;
@@ -1576,7 +1575,7 @@
     return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
                                  StopAtNul);
   }
-  
+
   // The GEP instruction, constant or instruction, must reference a global
   // variable that is a constant and is initialized. The referenced constant
   // initializer is the array that we'll use for optimization.
@@ -1585,8 +1584,8 @@
     return false;
   const Constant *GlobalInit = GV->getInitializer();
   
-  // Handle the ConstantAggregateZero case
-  if (isa<ConstantAggregateZero>(GlobalInit)) {
+  // Handle the all-zeros case
+  if (GlobalInit->isNullValue()) {
     // This is a degenerate case. The initializer is constant zero so the
     // length of the string must be zero.
     Str.clear();
@@ -1667,6 +1666,14 @@
     return Len1;
   }
 
+  // As a special-case, "@string = constant i8 0" is also a string with zero
+  // length, not wrapped in a bitcast or GEP.
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+    if (GV->isConstant() && GV->hasDefinitiveInitializer())
+      if (GV->getInitializer()->isNullValue()) return 1;
+    return 0;
+  }
+
   // If the value is not a GEP instruction nor a constant expression with a
   // GEP instruction, then return unknown.
   User *GEP = 0;

Modified: llvm/trunk/test/Transforms/SimplifyLibCalls/StrLen.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/StrLen.ll?rev=142558&r1=142557&r2=142558&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/StrLen.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/StrLen.ll Wed Oct 19 19:34:35 2011
@@ -6,6 +6,7 @@
 @hello = constant [6 x i8] c"hello\00"		; <[6 x i8]*> [#uses=3]
 @null = constant [1 x i8] zeroinitializer		; <[1 x i8]*> [#uses=3]
 @null_hello = constant [7 x i8] c"\00hello\00"		; <[7 x i8]*> [#uses=1]
+ at nullstring = constant i8 0
 
 declare i32 @strlen(i8*)
 
@@ -54,3 +55,8 @@
 	%ne_null = icmp ne i32 %null_l, 0		; <i1> [#uses=1]
 	ret i1 %ne_null
 }
+
+define i32 @test8() {
+	%len = tail call i32 @strlen(i8* @nullstring) nounwind
+	ret i32 %len
+}





More information about the llvm-commits mailing list