[LLVMbugs] Rewriting of strcmp bug and patch

John Mellor-Crummey johnmc at cs.rice.edu
Thu Jun 16 05:52:08 PDT 2005


strcmp of a string with null was being optimized away incorrectly. 
Rather than testing the first character
of the string, it was attempting to test the first character of the null.

In the example we were looking at, it seemed that we also were 
running into a similar problem with a missing cast (which we 
previously encountered with a bug rewriting sprintf); we applied the 
safe (cast if necessary) operation developed by Chris. Use of this 
static function in a new place required either a forward declaration 
of the function or moving the definition of the function. We moved 
the definition. You might prefer the forward declaration.

In any case, the patch is below.

John Mellor-Crummey


cvs diff -C3 SimplifyLibCalls.cpp
cvs diff: warning: failed to open /home/johnmc/.cvspass for reading: 
No such file or directory
Index: SimplifyLibCalls.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp,v
retrieving revision 1.42
diff -C3 -r1.42 SimplifyLibCalls.cpp
*** SimplifyLibCalls.cpp        21 May 2005 01:27:04 -0000      1.42
--- SimplifyLibCalls.cpp        16 Jun 2005 12:42:06 -0000
***************
*** 619,624 ****
--- 619,636 ----
     }
   } StrChrOptimizer;

+
+ /// CastToCStr - Return V if it is an sbyte*, otherwise cast it to sbyte*,
+ /// inserting the cast before IP, and return the cast.
+ /// @brief Cast a value to a "C" string.
+ static Value *CastToCStr(Value *V, Instruction &IP) {
+   const Type *SBPTy = PointerType::get(Type::SByteTy);
+   if (V->getType() != SBPTy)
+     return new CastInst(V, SBPTy, V->getName(), &IP);
+   return V;
+ }
+
+
   /// This LibCallOptimization will simplify a call to the strcmp library
   /// function.  It optimizes out cases where one or both arguments 
are constant
   /// and the result can be determined statically.
***************
*** 663,669 ****
         if (len_1 == 0)
         {
           // strcmp("",x) -> *x
!         LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci);
           CastInst* cast =
             new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
           ci->replaceAllUsesWith(cast);
--- 675,681 ----
         if (len_1 == 0)
         {
           // strcmp("",x) -> *x
!         LoadInst* load = new 
LoadInst(CastToCStr(s2,*ci),ci->getName()+".load",ci);
           CastInst* cast =
             new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
           ci->replaceAllUsesWith(cast);
***************
*** 681,687 ****
         if (len_2 == 0)
         {
           // strcmp(x,"") -> *x
!         LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci);
           CastInst* cast =
             new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
           ci->replaceAllUsesWith(cast);
--- 693,699 ----
         if (len_2 == 0)
         {
           // strcmp(x,"") -> *x
!         LoadInst* load = new 
LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci);
           CastInst* cast =
             new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
           ci->replaceAllUsesWith(cast);
***************
*** 1242,1256 ****
     }
   } PowOptimizer;

- /// CastToCStr - Return V if it is an sbyte*, otherwise cast it to sbyte*,
- /// inserting the cast before IP, and return the cast.
- /// @brief Cast a value to a "C" string.
- static Value *CastToCStr(Value *V, Instruction &IP) {
-   const Type *SBPTy = PointerType::get(Type::SByteTy);
-   if (V->getType() != SBPTy)
-     return new CastInst(V, SBPTy, V->getName(), &IP);
-   return V;
- }

   /// This LibCallOptimization will simplify calls to the "fprintf" library
   /// function. It looks for cases where the result of fprintf is not 
used and the
--- 1254,1259 ----




More information about the llvm-bugs mailing list