mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
This was introduced in a faulty refactoring (r225640, mea culpa): the tests weren't testing the return values, so, for both __strcpy_chk and __stpcpy_chk, we would return the end of the buffer (matching stpcpy) instead of the beginning (for strcpy). The root cause was the prefix "__" being ignored when comparing, which made us always pick LibFunc::stpcpy_chk. Pass the LibFunc::Func directly to avoid this kind of error. Also, make the testcases as explicit as possible to prevent this. The now-useful testcases expose another, entangled, stpcpy problem, with the further simplification. This was introduced in a refactoring (r225640) to match the original behavior. However, this leads to problems when successive simplifications generate several similar instructions, none of which are removed by the custom replaceAllUsesWith. For instance, InstCombine (the main user) doesn't erase the instruction in its custom RAUW. When trying to simplify say __stpcpy_chk: - first, an stpcpy is created (fortified simplifier), - second, a memcpy is created (normal simplifier), but the stpcpy call isn't removed. - third, InstCombine later revisits the instructions, and simplifies the first stpcpy to a memcpy. We now have two memcpys. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227250 91177308-0d34-0410-b5e6-96231b3b80d8
78 lines
2.8 KiB
LLVM
78 lines
2.8 KiB
LLVM
; Test lib call simplification of __memcpy_chk calls with various values
|
|
; for dstlen and len.
|
|
;
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
|
|
%struct.T1 = type { [100 x i32], [100 x i32], [1024 x i8] }
|
|
%struct.T2 = type { [100 x i32], [100 x i32], [1024 x i8] }
|
|
%struct.T3 = type { [100 x i32], [100 x i32], [2048 x i8] }
|
|
|
|
@t1 = common global %struct.T1 zeroinitializer
|
|
@t2 = common global %struct.T2 zeroinitializer
|
|
@t3 = common global %struct.T3 zeroinitializer
|
|
|
|
; Check cases where dstlen >= len.
|
|
|
|
define i8* @test_simplify1() {
|
|
; CHECK-LABEL: @test_simplify1(
|
|
%dst = bitcast %struct.T1* @t1 to i8*
|
|
%src = bitcast %struct.T2* @t2 to i8*
|
|
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1824, i32 4, i1 false)
|
|
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
|
|
%ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
|
|
ret i8* %ret
|
|
}
|
|
|
|
define i8* @test_simplify2() {
|
|
; CHECK-LABEL: @test_simplify2(
|
|
%dst = bitcast %struct.T1* @t1 to i8*
|
|
%src = bitcast %struct.T3* @t3 to i8*
|
|
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T3* @t3 to i8*), i64 1824, i32 4, i1 false)
|
|
; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
|
|
%ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
|
|
ret i8* %ret
|
|
}
|
|
|
|
; Check cases where dstlen < len.
|
|
|
|
define i8* @test_no_simplify1() {
|
|
; CHECK-LABEL: @test_no_simplify1(
|
|
%dst = bitcast %struct.T3* @t3 to i8*
|
|
%src = bitcast %struct.T1* @t1 to i8*
|
|
|
|
; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824)
|
|
; CHECK-NEXT: ret i8* %ret
|
|
%ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
|
|
ret i8* %ret
|
|
}
|
|
|
|
define i8* @test_no_simplify2() {
|
|
; CHECK-LABEL: @test_no_simplify2(
|
|
%dst = bitcast %struct.T1* @t1 to i8*
|
|
%src = bitcast %struct.T2* @t2 to i8*
|
|
|
|
; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0)
|
|
; CHECK-NEXT: ret i8* %ret
|
|
%ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
|
|
ret i8* %ret
|
|
}
|
|
|
|
define i8* @test_simplify_return_indcall(i8* ()* %alloc) {
|
|
; CHECK-LABEL: @test_simplify_return_indcall(
|
|
%src = bitcast %struct.T2* @t2 to i8*
|
|
|
|
; CHECK-NEXT: %dst = call i8* %alloc()
|
|
%dst = call i8* %alloc()
|
|
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
|
|
%ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
|
|
; CHECK-NEXT: ret i8* %dst
|
|
ret i8* %ret
|
|
}
|
|
|
|
declare i8* @__memcpy_chk(i8*, i8*, i64, i64)
|