[llvm-commits] [llvm] r61297 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/SimplifyLibCalls/2008-12-20-StrcmpMemcmp.ll

Nick Lewycky nicholas at mxc.ca
Mon Dec 22 16:09:51 PST 2008


Devang Patel wrote:
> Nick,
>
> 	char *s1 = "hi\0how are you";
> 	char *s2 = "hi\0I am fine  ";
>
> s1 and s2 are identical as per strcmp, but memcmp does not agree. Do  
> you handle this case ?
>   
Yes. GetStringLength is supposed to return the same length that strlen 
would have returned, stopping at the first null.
> -
> Devang
>
> On Dec 20, 2008, at 4:19 PM, Nick Lewycky wrote:
>
>   
>> Author: nicholas
>> Date: Sat Dec 20 18:19:21 2008
>> New Revision: 61297
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=61297&view=rev
>> Log:
>> Turn strcmp into memcmp, such as strcmp(P, "x") --> memcmp(P, "x", 2).
>>
>> Added:
>>    llvm/trunk/test/Transforms/SimplifyLibCalls/2008-12-20- 
>> StrcmpMemcmp.ll
>> Modified:
>>    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=61297&r1=61296&r2=61297&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> ======================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sat Dec 20  
>> 18:19:21 2008
>> @@ -80,7 +80,10 @@
>>   /// EmitMemChr - Emit a call to the memchr function.  This assumes  
>> that Ptr is
>>   /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
>>   Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<>  
>> &B);
>> -
>> +
>> +  /// EmitMemCmp - Emit a call to the memcmp function.
>> +  Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len,  
>> IRBuilder<> &B);
>> +
>>   /// EmitUnaryFloatFnCall - Emit a call to the unary function named  
>> 'Name' (e.g.
>>   /// 'floor').  This function is known to take a single of type  
>> matching 'Op'
>>   /// and returns one value with the same type.  If 'Op' is a long  
>> double, 'l'
>> @@ -106,7 +109,7 @@
>>   /// EmitFWrite - Emit a call to the fwrite function.  This assumes  
>> that Ptr is
>>   /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
>>   void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<>  
>> &B);
>> -
>> +
>> };
>> } // End anonymous namespace.
>>
>> @@ -151,6 +154,19 @@
>>   return B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len,  
>> "memchr");
>> }
>>
>> +/// EmitMemCmp - Emit a call to the memcmp function.
>> +Value *LibCallOptimization::EmitMemCmp(Value *Ptr1, Value *Ptr2,
>> +                                       Value *Len, IRBuilder<> &B) {
>> +  Module *M = Caller->getParent();
>> +  Value *MemCmp = M->getOrInsertFunction("memcmp",
>> +                                         Type::Int32Ty,
>> +                                          
>> PointerType::getUnqual(Type::Int8Ty),
>> +                                          
>> PointerType::getUnqual(Type::Int8Ty),
>> +                                         TD->getIntPtrType(), NULL);
>> +  return B.CreateCall3(MemCmp, CastToCStr(Ptr1, B),  
>> CastToCStr(Ptr2, B),
>> +                       Len, "memcmp");
>> +}
>> +
>> /// EmitUnaryFloatFnCall - Emit a call to the unary function named  
>> 'Name' (e.g.
>> /// 'floor').  This function is known to take a single of type  
>> matching 'Op' and
>> /// returns one value with the same type.  If 'Op' is a long double,  
>> 'l' is
>> @@ -537,6 +553,18 @@
>>     // strcmp(x, y)  -> cnst  (if both x and y are constant strings)
>>     if (HasStr1 && HasStr2)
>>       return ConstantInt::get(CI->getType(),  
>> strcmp(Str1.c_str(),Str2.c_str()));
>> +
>> +    // strcmp(P, "x") -> memcmp(P, "x", 2)
>> +    uint64_t Len1 = GetStringLength(Str1P);
>> +    uint64_t Len2 = GetStringLength(Str2P);
>> +    if (Len1 || Len2) {
>> +      // Choose the smallest Len excluding 0 which means 'unknown'.
>> +      if (!Len1 || (Len2 && Len2 < Len1))
>> +        Len1 = Len2;
>> +      return EmitMemCmp(Str1P, Str2P,
>> +                        ConstantInt::get(TD->getIntPtrType(),  
>> Len1), B);
>> +    }
>> +
>>     return 0;
>>   }
>> };
>>
>> Added: llvm/trunk/test/Transforms/SimplifyLibCalls/2008-12-20- 
>> StrcmpMemcmp.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/2008-12-20-StrcmpMemcmp.ll?rev=61297&view=auto
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> ======================================================================
>> --- llvm/trunk/test/Transforms/SimplifyLibCalls/2008-12-20- 
>> StrcmpMemcmp.ll (added)
>> +++ llvm/trunk/test/Transforms/SimplifyLibCalls/2008-12-20- 
>> StrcmpMemcmp.ll Sat Dec 20 18:19:21 2008
>> @@ -0,0 +1,10 @@
>> +; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep  
>> call.*memcmp
>> +
>> + at .str = internal constant [2 x i8] c"x\00"
>> +
>> +declare i32 @strcmp(i8* %dest, i8* %src)
>> +
>> +define i32 @foo(i8* %x, i8* %y) {
>> +  %A = call i32 @strcmp(i8* %x, i8* getelementptr ([2 x i8]* @.str,  
>> i32 0, i32 0))
>> +  ret i32 %A
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>     
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>   




More information about the llvm-commits mailing list