| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" |
| |
| @a = common global [60 x i8] zeroinitializer, align 1 |
| @b = common global [60 x i8] zeroinitializer, align 1 |
| @.str = private constant [12 x i8] c"abcdefghijk\00" |
| |
| %struct.__va_list_tag = type { i32, i32, ptr, ptr } |
| |
| define ptr @test_memccpy() { |
| ; CHECK-LABEL: @test_memccpy( |
| ; CHECK-NEXT: [[MEMCCPY:%.*]] = call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60) |
| ; CHECK-NEXT: ret ptr [[MEMCCPY]] |
| ; |
| %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1) |
| ret ptr %ret |
| } |
| |
| define ptr @test_not_memccpy() { |
| ; CHECK-LABEL: @test_not_memccpy( |
| ; CHECK-NEXT: [[RET:%.*]] = call ptr @__memccpy_chk(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60, i64 59) |
| ; CHECK-NEXT: ret ptr [[RET]] |
| ; |
| %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 59) |
| ret ptr %ret |
| } |
| |
| define ptr @test_memccpy_tail() { |
| ; CHECK-LABEL: @test_memccpy_tail( |
| ; CHECK-NEXT: [[MEMCCPY:%.*]] = tail call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60) |
| ; CHECK-NEXT: ret ptr [[MEMCCPY]] |
| ; |
| %ret = tail call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1) |
| ret ptr %ret |
| } |
| |
| define ptr @test_mempcpy() { |
| ; CHECK-LABEL: @test_mempcpy( |
| ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(15) @a, ptr noundef nonnull align 1 dereferenceable(15) @b, i64 15, i1 false) |
| ; CHECK-NEXT: ret ptr getelementptr inbounds ([60 x i8], ptr @a, i64 0, i64 15) |
| ; |
| %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1) |
| ret ptr %ret |
| } |
| |
| define ptr @test_not_mempcpy() { |
| ; CHECK-LABEL: @test_not_mempcpy( |
| ; CHECK-NEXT: [[RET:%.*]] = call ptr @__mempcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 60, i64 59) |
| ; CHECK-NEXT: ret ptr [[RET]] |
| ; |
| %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 60, i64 59) |
| ret ptr %ret |
| } |
| |
| define ptr @test_mempcpy_tail() { |
| ; CHECK-LABEL: @test_mempcpy_tail( |
| ; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(15) @a, ptr noundef nonnull align 1 dereferenceable(15) @b, i64 15, i1 false) |
| ; CHECK-NEXT: ret ptr getelementptr inbounds ([60 x i8], ptr @a, i64 0, i64 15) |
| ; |
| %ret = tail call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1) |
| ret ptr %ret |
| } |
| |
| define i32 @test_snprintf() { |
| ; CHECK-LABEL: @test_snprintf( |
| ; CHECK-NEXT: [[SNPRINTF:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b) |
| ; CHECK-NEXT: ret i32 [[SNPRINTF]] |
| ; |
| %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define i32 @test_not_snprintf() { |
| ; CHECK-LABEL: @test_not_snprintf( |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 0, i64 59, ptr nonnull @b) |
| ; CHECK-NEXT: [[IGN:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 1, i64 -1, ptr nonnull @b) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 59, ptr @b) |
| %ign = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 1, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define i32 @test_snprintf_tail() { |
| ; CHECK-LABEL: @test_snprintf_tail( |
| ; CHECK-NEXT: [[SNPRINTF:%.*]] = tail call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b) |
| ; CHECK-NEXT: ret i32 [[SNPRINTF]] |
| ; |
| %ret = tail call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define i32 @test_sprintf() { |
| ; CHECK-LABEL: @test_sprintf( |
| ; CHECK-NEXT: [[SPRINTF:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b) |
| ; CHECK-NEXT: ret i32 [[SPRINTF]] |
| ; |
| %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define i32 @test_not_sprintf() { |
| ; CHECK-LABEL: @test_not_sprintf( |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 0, i64 59, ptr nonnull @b) |
| ; CHECK-NEXT: [[IGNORED:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 59, ptr @b) |
| %ignored = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 1, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define i32 @test_sprintf_tail() { |
| ; CHECK-LABEL: @test_sprintf_tail( |
| ; CHECK-NEXT: [[SPRINTF:%.*]] = tail call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b) |
| ; CHECK-NEXT: ret i32 [[SPRINTF]] |
| ; |
| %ret = tail call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b) |
| ret i32 %ret |
| } |
| |
| define ptr @test_strcat() { |
| ; CHECK-LABEL: @test_strcat( |
| ; CHECK-NEXT: [[STRCAT:%.*]] = call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) |
| ; CHECK-NEXT: ret ptr @a |
| ; |
| %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1) |
| ret ptr %ret |
| } |
| |
| define ptr @test_not_strcat() { |
| ; CHECK-LABEL: @test_not_strcat( |
| ; CHECK-NEXT: [[RET:%.*]] = call ptr @__strcat_chk(ptr nonnull @a, ptr nonnull @b, i64 0) |
| ; CHECK-NEXT: ret ptr [[RET]] |
| ; |
| %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 0) |
| ret ptr %ret |
| } |
| |
| define ptr @test_strcat_tail() { |
| ; CHECK-LABEL: @test_strcat_tail( |
| ; CHECK-NEXT: [[STRCAT:%.*]] = tail call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) |
| ; CHECK-NEXT: ret ptr @a |
| ; |
| %ret = tail call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1) |
| ret ptr %ret |
| } |
| |
| define i64 @test_strlcat() { |
| ; CHECK-LABEL: @test_strlcat( |
| ; CHECK-NEXT: [[STRLCAT:%.*]] = call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22) |
| ; CHECK-NEXT: ret i64 [[STRLCAT]] |
| ; |
| %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret i64 %ret |
| } |
| |
| define i64 @test_not_strlcat() { |
| ; CHECK-LABEL: @test_not_strlcat( |
| ; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 0) |
| ; CHECK-NEXT: ret i64 [[RET]] |
| ; |
| %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 0) |
| ret i64 %ret |
| } |
| |
| define i64 @test_strlcat_tail() { |
| ; CHECK-LABEL: @test_strlcat_tail( |
| ; CHECK-NEXT: [[STRLCAT:%.*]] = tail call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22) |
| ; CHECK-NEXT: ret i64 [[STRLCAT]] |
| ; |
| %ret = tail call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret i64 %ret |
| } |
| |
| define ptr @test_strncat() { |
| ; CHECK-LABEL: @test_strncat( |
| ; CHECK-NEXT: [[STRNCAT:%.*]] = call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) |
| ; CHECK-NEXT: ret ptr @a |
| ; |
| %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret ptr %ret |
| } |
| |
| define ptr @test_not_strncat() { |
| ; CHECK-LABEL: @test_not_strncat( |
| ; CHECK-NEXT: [[RET:%.*]] = call ptr @__strncat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 3) |
| ; CHECK-NEXT: ret ptr [[RET]] |
| ; |
| %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 3) |
| ret ptr %ret |
| } |
| |
| define ptr @test_strncat_tail() { |
| ; CHECK-LABEL: @test_strncat_tail( |
| ; CHECK-NEXT: [[STRNCAT:%.*]] = tail call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) |
| ; CHECK-NEXT: ret ptr @a |
| ; |
| %ret = tail call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret ptr %ret |
| } |
| |
| define i64 @test_strlcpy() { |
| ; CHECK-LABEL: @test_strlcpy( |
| ; CHECK-NEXT: [[STRLCPY:%.*]] = call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) |
| ; CHECK-NEXT: ret i64 [[STRLCPY]] |
| ; |
| %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret i64 %ret |
| } |
| |
| define i64 @test_not_strlcpy() { |
| ; CHECK-LABEL: @test_not_strlcpy( |
| ; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 2) |
| ; CHECK-NEXT: ret i64 [[RET]] |
| ; |
| %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 2) |
| ret i64 %ret |
| } |
| |
| define i64 @test_strlcpy_tail() { |
| ; CHECK-LABEL: @test_strlcpy_tail( |
| ; CHECK-NEXT: [[STRLCPY:%.*]] = tail call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) |
| ; CHECK-NEXT: ret i64 [[STRLCPY]] |
| ; |
| %ret = tail call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1) |
| ret i64 %ret |
| } |
| |
| define i32 @test_vsnprintf() { |
| ; CHECK-LABEL: @test_vsnprintf( |
| ; CHECK-NEXT: [[VSNPRINTF:%.*]] = call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[VSNPRINTF]] |
| ; |
| ; ret i32 |
| %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| define i32 @test_not_vsnprintf() { |
| ; CHECK-LABEL: @test_not_vsnprintf( |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 0, i64 3, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 1, i64 -1, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| ; ret i32 |
| %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 3, ptr @b, ptr null) |
| %ign = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 1, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| define i32 @test_vsnprintf_tail() { |
| ; CHECK-LABEL: @test_vsnprintf_tail( |
| ; CHECK-NEXT: [[VSNPRINTF:%.*]] = tail call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[VSNPRINTF]] |
| ; |
| ; ret i32 |
| %ret = tail call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| define i32 @test_vsprintf() { |
| ; CHECK-LABEL: @test_vsprintf( |
| ; CHECK-NEXT: [[VSPRINTF:%.*]] = call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[VSPRINTF]] |
| ; |
| ; ret i32 |
| %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| define i32 @test_not_vsprintf() { |
| ; CHECK-LABEL: @test_not_vsprintf( |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 0, i64 3, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| ; ret i32 |
| %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 3, ptr @b, ptr null) |
| %ign = call i32 @__vsprintf_chk(ptr @a, i32 1, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| define i32 @test_vsprintf_tail() { |
| ; CHECK-LABEL: @test_vsprintf_tail( |
| ; CHECK-NEXT: [[VSPRINTF:%.*]] = tail call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null) |
| ; CHECK-NEXT: ret i32 [[VSPRINTF]] |
| ; |
| ; ret i32 |
| %ret = tail call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null) |
| ret i32 %ret |
| } |
| |
| declare ptr @__mempcpy_chk(ptr, ptr, i64, i64) |
| declare ptr @__memccpy_chk(ptr, ptr, i32, i64, i64) |
| declare i32 @__snprintf_chk(ptr, i64, i32, i64, ptr, ...) |
| declare i32 @__sprintf_chk(ptr, i32, i64, ptr, ...) |
| declare ptr @__strcat_chk(ptr, ptr, i64) |
| declare i64 @__strlcat_chk(ptr, ptr, i64, i64) |
| declare ptr @__strncat_chk(ptr, ptr, i64, i64) |
| declare i64 @__strlcpy_chk(ptr, ptr, i64, i64) |
| declare i32 @__vsnprintf_chk(ptr, i64, i32, i64, ptr, ptr) |
| declare i32 @__vsprintf_chk(ptr, i32, i64, ptr, ptr) |