Normalize memcmp constant folding results.
authorMeador Inge <meadori@codesourcery.com>
Mon, 12 Nov 2012 14:00:45 +0000 (14:00 +0000)
committerMeador Inge <meadori@codesourcery.com>
Mon, 12 Nov 2012 14:00:45 +0000 (14:00 +0000)
The library call simplifier folds memcmp calls with all constant arguments
to a constant.  For example:

  memcmp("foo", "foo", 3) ->  0
  memcmp("hel", "foo", 3) ->  1
  memcmp("foo", "hel", 3) -> -1

The folding is implemented in terms of the system memcmp that LLVM gets
linked with.  It currently just blindly uses the value returned from
the system memcmp as the folded constant.

This patch normalizes the values returned from the system memcmp to
(-1, 0, 1) so that we get consistent results across multiple platforms.
The test cases were adjusted accordingly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167726 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/SimplifyLibCalls.cpp
test/Transforms/InstCombine/memcmp-1.ll

index c3ea63852fedae4b96d6338fd96c129efb9df32a..20281181b2a79f4691e8ec6a3db974e73c5548e1 100644 (file)
@@ -951,7 +951,14 @@ struct MemCmpOpt : public LibCallOptimization {
       // Make sure we're not reading out-of-bounds memory.
       if (Len > LHSStr.size() || Len > RHSStr.size())
         return 0;
-      uint64_t Ret = memcmp(LHSStr.data(), RHSStr.data(), Len);
+      // Fold the memcmp and normalize the result.  This way we get consistent
+      // results across multiple platforms.
+      uint64_t Ret = 0;
+      int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len);
+      if (Cmp < 0)
+        Ret = -1;
+      else if (Cmp > 0)
+        Ret = 1;
       return ConstantInt::get(CI->getType(), Ret);
     }
 
index 4238c5f8fb153280b5b02b442ca66ee19b7979f9..c97b201fc0e94ecedbfd8acb02be2b1fedef4976 100644 (file)
@@ -59,7 +59,7 @@ define i32 @test_simplify5() {
   %mem2 = getelementptr [4 x i8]* @foo, i32 0, i32 0
   %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3)
   ret i32 %ret
-; CHECK: ret i32 {{[0-9]+}}
+; CHECK: ret i32 1
 }
 
 define i32 @test_simplify6() {
@@ -68,5 +68,5 @@ define i32 @test_simplify6() {
   %mem2 = getelementptr [4 x i8]* @hel, i32 0, i32 0
   %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3)
   ret i32 %ret
-; CHECK: ret i32 {{-[0-9]+}}
+; CHECK: ret i32 -1
 }