diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 22a605d86fc..1003269e289 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -76,8 +76,12 @@ namespace llvm { /// GetConstantStringInfo - This function computes the length of a /// 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 GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0); + /// and returns the string in Str. If unsuccessful, it returns false. If + /// StopAtNul is set to true (the default), the returned string is truncated + /// by a nul character in the global. If StopAtNul is false, the nul + /// character is included in the result string. + bool GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0, + bool StopAtNul = true); } // end namespace llvm #endif diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index c80489153aa..e7e291fb928 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -935,13 +935,14 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin, /// GetConstantStringInfo - This function computes the length of a /// 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(Value *V, std::string &Str, uint64_t Offset) { +bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset, + bool StopAtNul) { // If V is NULL then return false; if (V == NULL) return false; // Look through bitcast instructions. if (BitCastInst *BCI = dyn_cast(V)) - return GetConstantStringInfo(BCI->getOperand(0), Str, Offset); + return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul); // If the value is not a GEP instruction nor a constant expression with a // GEP instruction, then return false because ConstantArray can't occur @@ -951,7 +952,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset) { GEP = GEPI; } else if (ConstantExpr *CE = dyn_cast(V)) { if (CE->getOpcode() == Instruction::BitCast) - return GetConstantStringInfo(CE->getOperand(0), Str, Offset); + return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul); if (CE->getOpcode() != Instruction::GetElementPtr) return false; GEP = CE; @@ -982,7 +983,8 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset) { StartIdx = CI->getZExtValue(); else return false; - return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset); + return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset, + StopAtNul); } // The GEP instruction, constant or instruction, must reference a global @@ -1020,7 +1022,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset) { ConstantInt *CI = dyn_cast(Elt); if (!CI) // This array isn't suitable, non-int initializer. return false; - if (CI->isZero()) + if (StopAtNul && CI->isZero()) return true; // we found end of string, success! Str += (char)CI->getZExtValue(); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 65d2d6ba380..717ad34f408 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2594,7 +2594,7 @@ static bool isMemSrcFromString(SDOperand Src, std::string &Str, return false; GlobalVariable *GV = dyn_cast(G->getGlobal()); - if (GV && GetConstantStringInfo(GV, Str)) { + if (GV && GetConstantStringInfo(GV, Str, SrcDelta, false)) { SrcOff += SrcDelta; return true; }