[llvm-commits] [PATCH 2/3] instcombine: Migrate strcat and strncat optimizations

Eric Christopher echristo at gmail.com
Fri Oct 12 15:20:36 PDT 2012


Looks mechanical provided the earlier patch was approved?

-eric

On Mon, Oct 8, 2012 at 8:25 AM, Meador Inge <meadori at codesourcery.com> wrote:
> This patch migrates the strcat and strncat optimizations from the
> simplify-libcalls pass into the instcombine library call simplifier.
> ---
>  lib/Transforms/Scalar/SimplifyLibCalls.cpp  |  102 +-------------------------
>  lib/Transforms/Utils/SimplifyLibCalls.cpp   |  106 +++++++++++++++++++++++++++
>  test/Transforms/InstCombine/strcat-1.ll     |   38 ++++++++++
>  test/Transforms/InstCombine/strcat-2.ll     |   32 ++++++++
>  test/Transforms/InstCombine/strcat-3.ll     |   22 ++++++
>  test/Transforms/InstCombine/strncat-1.ll    |   37 ++++++++++
>  test/Transforms/InstCombine/strncat-2.ll    |   53 ++++++++++++++
>  test/Transforms/InstCombine/strncat-3.ll    |   22 ++++++
>  test/Transforms/SimplifyLibCalls/StrCat.ll  |   33 ---------
>  test/Transforms/SimplifyLibCalls/StrNCat.ll |   31 --------
>  10 files changed, 311 insertions(+), 165 deletions(-)
>  create mode 100644 test/Transforms/InstCombine/strcat-1.ll
>  create mode 100644 test/Transforms/InstCombine/strcat-2.ll
>  create mode 100644 test/Transforms/InstCombine/strcat-3.ll
>  create mode 100644 test/Transforms/InstCombine/strncat-1.ll
>  create mode 100644 test/Transforms/InstCombine/strncat-2.ll
>  create mode 100644 test/Transforms/InstCombine/strncat-3.ll
>  delete mode 100644 test/Transforms/SimplifyLibCalls/StrCat.ll
>  delete mode 100644 test/Transforms/SimplifyLibCalls/StrNCat.ll
>
> diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
> index 65311fe..88586d9 100644
> --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
> +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
> @@ -133,105 +133,7 @@ static bool IsOnlyUsedInEqualityComparison(Value *V, Value *With) {
>  // String and Memory LibCall Optimizations
>  //===----------------------------------------------------------------------===//
>
> -//===---------------------------------------===//
> -// 'strcat' Optimizations
>  namespace {
> -struct StrCatOpt : public LibCallOptimization {
> -  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> -    // Verify the "strcat" function prototype.
> -    FunctionType *FT = Callee->getFunctionType();
> -    if (FT->getNumParams() != 2 ||
> -        FT->getReturnType() != B.getInt8PtrTy() ||
> -        FT->getParamType(0) != FT->getReturnType() ||
> -        FT->getParamType(1) != FT->getReturnType())
> -      return 0;
> -
> -    // Extract some information from the instruction
> -    Value *Dst = CI->getArgOperand(0);
> -    Value *Src = CI->getArgOperand(1);
> -
> -    // See if we can get the length of the input string.
> -    uint64_t Len = GetStringLength(Src);
> -    if (Len == 0) return 0;
> -    --Len;  // Unbias length.
> -
> -    // Handle the simple, do-nothing case: strcat(x, "") -> x
> -    if (Len == 0)
> -      return Dst;
> -
> -    // These optimizations require TargetData.
> -    if (!TD) return 0;
> -
> -    return EmitStrLenMemCpy(Src, Dst, Len, B);
> -  }
> -
> -  Value *EmitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B) {
> -    // We need to find the end of the destination string.  That's where the
> -    // memory is to be moved to. We just generate a call to strlen.
> -    Value *DstLen = EmitStrLen(Dst, B, TD, TLI);
> -    if (!DstLen)
> -      return 0;
> -
> -    // Now that we have the destination's length, we must index into the
> -    // destination's pointer to get the actual memcpy destination (end of
> -    // the string .. we're concatenating).
> -    Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
> -
> -    // We have enough information to now generate the memcpy call to do the
> -    // concatenation for us.  Make a memcpy to copy the nul byte with align = 1.
> -    B.CreateMemCpy(CpyDst, Src,
> -                   ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1);
> -    return Dst;
> -  }
> -};
> -
> -//===---------------------------------------===//
> -// 'strncat' Optimizations
> -
> -struct StrNCatOpt : public StrCatOpt {
> -  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> -    // Verify the "strncat" function prototype.
> -    FunctionType *FT = Callee->getFunctionType();
> -    if (FT->getNumParams() != 3 ||
> -        FT->getReturnType() != B.getInt8PtrTy() ||
> -        FT->getParamType(0) != FT->getReturnType() ||
> -        FT->getParamType(1) != FT->getReturnType() ||
> -        !FT->getParamType(2)->isIntegerTy())
> -      return 0;
> -
> -    // Extract some information from the instruction
> -    Value *Dst = CI->getArgOperand(0);
> -    Value *Src = CI->getArgOperand(1);
> -    uint64_t Len;
> -
> -    // We don't do anything if length is not constant
> -    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
> -      Len = LengthArg->getZExtValue();
> -    else
> -      return 0;
> -
> -    // See if we can get the length of the input string.
> -    uint64_t SrcLen = GetStringLength(Src);
> -    if (SrcLen == 0) return 0;
> -    --SrcLen;  // Unbias length.
> -
> -    // Handle the simple, do-nothing cases:
> -    // strncat(x, "", c) -> x
> -    // strncat(x,  c, 0) -> x
> -    if (SrcLen == 0 || Len == 0) return Dst;
> -
> -    // These optimizations require TargetData.
> -    if (!TD) return 0;
> -
> -    // We don't optimize this case
> -    if (Len < SrcLen) return 0;
> -
> -    // strncat(x, s, c) -> strcat(x, s)
> -    // s is constant so the strcat can be optimized further
> -    return EmitStrLenMemCpy(Src, Dst, SrcLen, B);
> -  }
> -};
> -
>  //===---------------------------------------===//
>  // 'strchr' Optimizations
>
> @@ -1562,7 +1464,7 @@ namespace {
>
>      StringMap<LibCallOptimization*> Optimizations;
>      // String and Memory LibCall Optimizations
> -    StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrRChrOpt StrRChr;
> +    StrChrOpt StrChr; StrRChrOpt StrRChr;
>      StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
>      StrCpyOpt StrCpy; StrCpyOpt StrCpyChk;
>      StpCpyOpt StpCpy; StpCpyOpt StpCpyChk;
> @@ -1637,8 +1539,6 @@ void SimplifyLibCalls::AddOpt(LibFunc::Func F1, LibFunc::Func F2,
>  /// we know.
>  void SimplifyLibCalls::InitOptimizations() {
>    // String and Memory LibCall Optimizations
> -  Optimizations["strcat"] = &StrCat;
> -  Optimizations["strncat"] = &StrNCat;
>    Optimizations["strchr"] = &StrChr;
>    Optimizations["strrchr"] = &StrRChr;
>    Optimizations["strcmp"] = &StrCmp;
> diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp
> index c45783d..f4e6af8 100644
> --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp
> +++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp
> @@ -222,6 +222,104 @@ struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization {
>    }
>  };
>
> +//===----------------------------------------------------------------------===//
> +// String and Memory Library Call Optimizations
> +//===----------------------------------------------------------------------===//
> +
> +struct StrCatOpt : public LibCallOptimization {
> +  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> +    // Verify the "strcat" function prototype.
> +    FunctionType *FT = Callee->getFunctionType();
> +    if (FT->getNumParams() != 2 ||
> +        FT->getReturnType() != B.getInt8PtrTy() ||
> +        FT->getParamType(0) != FT->getReturnType() ||
> +        FT->getParamType(1) != FT->getReturnType())
> +      return 0;
> +
> +    // Extract some information from the instruction
> +    Value *Dst = CI->getArgOperand(0);
> +    Value *Src = CI->getArgOperand(1);
> +
> +    // See if we can get the length of the input string.
> +    uint64_t Len = GetStringLength(Src);
> +    if (Len == 0) return 0;
> +    --Len;  // Unbias length.
> +
> +    // Handle the simple, do-nothing case: strcat(x, "") -> x
> +    if (Len == 0)
> +      return Dst;
> +
> +    // These optimizations require TargetData.
> +    if (!TD) return 0;
> +
> +    return emitStrLenMemCpy(Src, Dst, Len, B);
> +  }
> +
> +  Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
> +                          IRBuilder<> &B) {
> +    // We need to find the end of the destination string.  That's where the
> +    // memory is to be moved to. We just generate a call to strlen.
> +    Value *DstLen = EmitStrLen(Dst, B, TD, TLI);
> +    if (!DstLen)
> +      return 0;
> +
> +    // Now that we have the destination's length, we must index into the
> +    // destination's pointer to get the actual memcpy destination (end of
> +    // the string .. we're concatenating).
> +    Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
> +
> +    // We have enough information to now generate the memcpy call to do the
> +    // concatenation for us.  Make a memcpy to copy the nul byte with align = 1.
> +    B.CreateMemCpy(CpyDst, Src,
> +                   ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1);
> +    return Dst;
> +  }
> +};
> +
> +struct StrNCatOpt : public StrCatOpt {
> +  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> +    // Verify the "strncat" function prototype.
> +    FunctionType *FT = Callee->getFunctionType();
> +    if (FT->getNumParams() != 3 ||
> +        FT->getReturnType() != B.getInt8PtrTy() ||
> +        FT->getParamType(0) != FT->getReturnType() ||
> +        FT->getParamType(1) != FT->getReturnType() ||
> +        !FT->getParamType(2)->isIntegerTy())
> +      return 0;
> +
> +    // Extract some information from the instruction
> +    Value *Dst = CI->getArgOperand(0);
> +    Value *Src = CI->getArgOperand(1);
> +    uint64_t Len;
> +
> +    // We don't do anything if length is not constant
> +    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
> +      Len = LengthArg->getZExtValue();
> +    else
> +      return 0;
> +
> +    // See if we can get the length of the input string.
> +    uint64_t SrcLen = GetStringLength(Src);
> +    if (SrcLen == 0) return 0;
> +    --SrcLen;  // Unbias length.
> +
> +    // Handle the simple, do-nothing cases:
> +    // strncat(x, "", c) -> x
> +    // strncat(x,  c, 0) -> x
> +    if (SrcLen == 0 || Len == 0) return Dst;
> +
> +    // These optimizations require TargetData.
> +    if (!TD) return 0;
> +
> +    // We don't optimize this case
> +    if (Len < SrcLen) return 0;
> +
> +    // strncat(x, s, c) -> strcat(x, s)
> +    // s is constant so the strcat can be optimized further
> +    return emitStrLenMemCpy(Src, Dst, SrcLen, B);
> +  }
> +};
> +
>  } // End anonymous namespace.
>
>  namespace llvm {
> @@ -239,6 +337,10 @@ class LibCallSimplifierImpl {
>    StrCpyChkOpt StrCpyChk;
>    StrNCpyChkOpt StrNCpyChk;
>
> +  // String and memory library call optimizations.
> +  StrCatOpt StrCat;
> +  StrNCatOpt StrNCat;
> +
>    void initOptimizations();
>  public:
>    LibCallSimplifierImpl(const TargetData *TD, const TargetLibraryInfo *TLI) {
> @@ -258,6 +360,10 @@ void LibCallSimplifierImpl::initOptimizations() {
>    Optimizations["__stpcpy_chk"] = &StrCpyChk;
>    Optimizations["__strncpy_chk"] = &StrNCpyChk;
>    Optimizations["__stpncpy_chk"] = &StrNCpyChk;
> +
> +  // String and memory library call optimizations.
> +  Optimizations["strcat"] = &StrCat;
> +  Optimizations["strncat"] = &StrNCat;
>  }
>
>  Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
> diff --git a/test/Transforms/InstCombine/strcat-1.ll b/test/Transforms/InstCombine/strcat-1.ll
> new file mode 100644
> index 0000000..3c05d6b
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strcat-1.ll
> @@ -0,0 +1,38 @@
> +; Test that the strcat libcall simplifier works correctly per the
> +; bug found in PR3661.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at null = constant [1 x i8] zeroinitializer
> + at null_hello = constant [7 x i8] c"\00hello\00"
> +
> +declare i8* @strcat(i8*, i8*)
> +declare i32 @puts(i8*)
> +
> +define i32 @main() {
> +; CHECK: @main
> +; CHECK-NOT: call i8* @strcat
> +; CHECK: call i32 @puts
> +
> +  %target = alloca [1024 x i8]
> +  %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0
> +  store i8 0, i8* %arg1
> +
> +  ; rslt1 = strcat(target, "hello\00")
> +  %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  %rslt1 = call i8* @strcat(i8* %arg1, i8* %arg2)
> +
> +  ; rslt2 = strcat(rslt1, "\00")
> +  %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0
> +  %rslt2 = call i8* @strcat(i8* %rslt1, i8* %arg3)
> +
> +  ; rslt3 = strcat(rslt2, "\00hello\00")
> +  %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0
> +  %rslt3 = call i8* @strcat(i8* %rslt2, i8* %arg4)
> +
> +  call i32 @puts( i8* %rslt3 )
> +  ret i32 0
> +}
> diff --git a/test/Transforms/InstCombine/strcat-2.ll b/test/Transforms/InstCombine/strcat-2.ll
> new file mode 100644
> index 0000000..379ee74
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strcat-2.ll
> @@ -0,0 +1,32 @@
> +; Test that the strcat libcall simplifier works correctly.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at empty = constant [1 x i8] c"\00"
> + at a = common global [32 x i8] zeroinitializer, align 1
> +
> +declare i8* @strcat(i8*, i8*)
> +
> +define void @test_simplify1() {
> +; CHECK: @test_simplify1
> +; CHECK-NOT: call i8* @strcat
> +; CHECK: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i8* @strcat(i8* %dst, i8* %src)
> +  ret void
> +}
> +
> +define void @test_simplify2() {
> +; CHECK: @test_simplify2
> +; CHECK-NEXT: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [1 x i8]* @empty, i32 0, i32 0
> +  call i8* @strcat(i8* %dst, i8* %src)
> +  ret void
> +}
> diff --git a/test/Transforms/InstCombine/strcat-3.ll b/test/Transforms/InstCombine/strcat-3.ll
> new file mode 100644
> index 0000000..15aff2f
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strcat-3.ll
> @@ -0,0 +1,22 @@
> +; Test that the strcat libcall simplifier works correctly.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at empty = constant [1 x i8] c"\00"
> + at a = common global [32 x i8] zeroinitializer, align 1
> +
> +declare i16* @strcat(i8*, i8*)
> +
> +define void @test_nosimplify1() {
> +; CHECK: @test_nosimplify1
> +; CHECK: call i16* @strcat
> +; CHECK: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i16* @strcat(i8* %dst, i8* %src)
> +  ret void
> +}
> diff --git a/test/Transforms/InstCombine/strncat-1.ll b/test/Transforms/InstCombine/strncat-1.ll
> new file mode 100644
> index 0000000..ad2a18b
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strncat-1.ll
> @@ -0,0 +1,37 @@
> +; Test that the strncat libcall simplifier works correctly.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at null = constant [1 x i8] zeroinitializer
> + at null_hello = constant [7 x i8] c"\00hello\00"
> +
> +declare i8* @strncat(i8*, i8*, i32)
> +declare i32 @puts(i8*)
> +
> +define i32 @main() {
> +; CHECK: @main
> +; CHECK-NOT: call i8* @strncat
> +; CHECK: call i32 @puts
> +
> +  %target = alloca [1024 x i8]
> +  %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0
> +  store i8 0, i8* %arg1
> +
> +  ; rslt1 = strncat(target, "hello\00")
> +  %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  %rslt1 = call i8* @strncat(i8* %arg1, i8* %arg2, i32 6)
> +
> +  ; rslt2 = strncat(rslt1, "\00")
> +  %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0
> +  %rslt2 = call i8* @strncat(i8* %rslt1, i8* %arg3, i32 42)
> +
> +  ; rslt3 = strncat(rslt2, "\00hello\00")
> +  %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0
> +  %rslt3 = call i8* @strncat(i8* %rslt2, i8* %arg4, i32 42)
> +
> +  call i32 @puts(i8* %rslt3)
> +  ret i32 0
> +}
> diff --git a/test/Transforms/InstCombine/strncat-2.ll b/test/Transforms/InstCombine/strncat-2.ll
> new file mode 100644
> index 0000000..c56deac
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strncat-2.ll
> @@ -0,0 +1,53 @@
> +; Test that the strncat libcall simplifier works correctly.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at empty = constant [1 x i8] c"\00"
> + at a = common global [32 x i8] zeroinitializer, align 1
> +
> +declare i8* @strncat(i8*, i8*, i32)
> +
> +define void @test_simplify1() {
> +; CHECK: @test_simplify1
> +; CHECK-NOT: call i8* @strncat
> +; CHECK: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i8* @strncat(i8* %dst, i8* %src, i32 13)
> +  ret void
> +}
> +
> +define void @test_simplify2() {
> +; CHECK: @test_simplify2
> +; CHECK-NEXT: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [1 x i8]* @empty, i32 0, i32 0
> +  call i8* @strncat(i8* %dst, i8* %src, i32 13)
> +  ret void
> +}
> +
> +define void @test_simplify3() {
> +; CHECK: @test_simplify3
> +; CHECK-NEXT: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i8* @strncat(i8* %dst, i8* %src, i32 0)
> +  ret void
> +}
> +
> +define void @test_nosimplify1() {
> +; CHECK: @test_nosimplify1
> +; CHECK: call i8* @strncat
> +; CHECK: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i8* @strncat(i8* %dst, i8* %src, i32 1)
> +  ret void
> +}
> diff --git a/test/Transforms/InstCombine/strncat-3.ll b/test/Transforms/InstCombine/strncat-3.ll
> new file mode 100644
> index 0000000..3cd7971
> --- /dev/null
> +++ b/test/Transforms/InstCombine/strncat-3.ll
> @@ -0,0 +1,22 @@
> +; Test that the strncat libcall simplifier works correctly.
> +;
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
> +
> + at hello = constant [6 x i8] c"hello\00"
> + at empty = constant [1 x i8] c"\00"
> + at a = common global [32 x i8] zeroinitializer, align 1
> +
> +declare i16* @strncat(i8*, i8*, i32)
> +
> +define void @test_nosimplify1() {
> +; CHECK: @test_nosimplify1
> +; CHECK: call i16* @strncat
> +; CHECK: ret void
> +
> +  %dst = getelementptr [32 x i8]* @a, i32 0, i32 0
> +  %src = getelementptr [6 x i8]* @hello, i32 0, i32 0
> +  call i16* @strncat(i8* %dst, i8* %src, i32 13)
> +  ret void
> +}
> diff --git a/test/Transforms/SimplifyLibCalls/StrCat.ll b/test/Transforms/SimplifyLibCalls/StrCat.ll
> deleted file mode 100644
> index 3ea691a..0000000
> --- a/test/Transforms/SimplifyLibCalls/StrCat.ll
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -; Test that the StrCatOptimizer works correctly
> -; PR3661
> -; RUN: opt < %s -simplify-libcalls -S | \
> -; RUN:   not grep "call.*strcat"
> -; RUN: opt < %s -simplify-libcalls -S | \
> -; RUN:   grep "puts.*%arg1"
> -
> -; This transformation requires the pointer size, as it assumes that size_t is
> -; the size of a pointer.
> -target datalayout = "-p:64:64:64"
> -
> - at hello = constant [6 x i8] c"hello\00"         ; <[6 x i8]*> [#uses=1]
> - at null = constant [1 x i8] zeroinitializer              ; <[1 x i8]*> [#uses=1]
> - at null_hello = constant [7 x i8] c"\00hello\00"         ; <[7 x i8]*> [#uses=1]
> -
> -declare i8* @strcat(i8*, i8*)
> -
> -declare i32 @puts(i8*)
> -
> -define i32 @main() {
> -       %target = alloca [1024 x i8]            ; <[1024 x i8]*> [#uses=1]
> -       %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0                ; <i8*> [#uses=2]
> -       store i8 0, i8* %arg1
> -       %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0            ; <i8*> [#uses=1]
> -       %rslt1 = call i8* @strcat( i8* %arg1, i8* %arg2 )               ; <i8*> [#uses=1]
> -       %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0             ; <i8*> [#uses=1]
> -       %rslt2 = call i8* @strcat( i8* %rslt1, i8* %arg3 )              ; <i8*> [#uses=1]
> -       %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0               ; <i8*> [#uses=1]
> -       %rslt3 = call i8* @strcat( i8* %rslt2, i8* %arg4 )              ; <i8*> [#uses=1]
> -       call i32 @puts( i8* %rslt3 )            ; <i32>:1 [#uses=0]
> -       ret i32 0
> -}
> -
> diff --git a/test/Transforms/SimplifyLibCalls/StrNCat.ll b/test/Transforms/SimplifyLibCalls/StrNCat.ll
> deleted file mode 100644
> index 073792b..0000000
> --- a/test/Transforms/SimplifyLibCalls/StrNCat.ll
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -; Test that the StrNCatOptimizer works correctly
> -; RUN: opt < %s -simplify-libcalls -S | \
> -; RUN:   not grep "call.*strncat"
> -; RUN: opt < %s -simplify-libcalls -S | \
> -; RUN:   grep "puts.*%arg1"
> -
> -; This transformation requires the pointer size, as it assumes that size_t is
> -; the size of a pointer.
> -target datalayout = "-p:64:64:64"
> -
> - at hello = constant [6 x i8] c"hello\00"         ; <[6 x i8]*> [#uses=1]
> - at null = constant [1 x i8] zeroinitializer              ; <[1 x i8]*> [#uses=1]
> - at null_hello = constant [7 x i8] c"\00hello\00"         ; <[7 x i8]*> [#uses=1]
> -
> -declare i8* @strncat(i8*, i8*, i32)
> -
> -declare i32 @puts(i8*)
> -
> -define i32 @main() {
> -       %target = alloca [1024 x i8]            ; <[1024 x i8]*> [#uses=1]
> -       %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0                ; <i8*> [#uses=2]
> -       store i8 0, i8* %arg1
> -       %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0            ; <i8*> [#uses=1]
> -       %rslt1 = call i8* @strncat( i8* %arg1, i8* %arg2, i32 6 )               ; <i8*> [#uses=1]
> -       %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0             ; <i8*> [#uses=1]
> -       %rslt2 = call i8* @strncat( i8* %rslt1, i8* %arg3, i32 42 )             ; <i8*> [#uses=1]
> -       %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0               ; <i8*> [#uses=1]
> -       %rslt3 = call i8* @strncat( i8* %rslt2, i8* %arg4, i32 42 )             ; <i8*> [#uses=1]
> -       call i32 @puts( i8* %rslt3 )            ; <i32>:1 [#uses=0]
> -       ret i32 0
> -}
> --
> 1.7.10.2 (Apple Git-33)
>
> _______________________________________________
> 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