175 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Test that the sprintf library call simplifier works correctly.3;4; RUN: opt < %s -passes=instcombine -S | FileCheck %s5; RUN: opt < %s -mtriple xcore-xmos-elf -passes=instcombine -S | FileCheck %s -check-prefixes=CHECK,WITHSTPCPY,CHECK-IPRINTF6; RUN: opt < %s -mtriple=i386-pc-windows-msvc -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,NOSTPCPY7; RUN: opt < %s -mtriple=i386-mingw32 -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,NOSTPCPY8; RUN: opt < %s -mtriple=armv7-none-linux-android -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,WITHSTPCPY9; RUN: opt < %s -mtriple=x86_64-scei-ps4 -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,NOSTPCPY10 11target 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"12 13@hello_world = constant [13 x i8] c"hello world\0A\00"14@null = constant [1 x i8] zeroinitializer15@null_hello = constant [7 x i8] c"\00hello\00"16@h = constant [2 x i8] c"h\00"17@percent_c = constant [3 x i8] c"%c\00"18@percent_d = constant [3 x i8] c"%d\00"19@percent_f = constant [3 x i8] c"%f\00"20@percent_s = constant [3 x i8] c"%s\00"21 22declare i32 @sprintf(ptr, ptr, ...)23 24; Check sprintf(dst, fmt) -> llvm.memcpy(str, fmt, strlen(fmt) + 1, 1).25 26define void @test_simplify1(ptr %dst) {27; CHECK-LABEL: @test_simplify1(28; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(13) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(13) @hello_world, i32 13, i1 false)29; CHECK-NEXT: ret void30;31 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @hello_world)32 ret void33}34 35define void @test_simplify2(ptr %dst) {36; CHECK-LABEL: @test_simplify2(37; CHECK-NEXT: store i8 0, ptr [[DST:%.*]], align 138; CHECK-NEXT: ret void39;40 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @null)41 ret void42}43 44define void @test_simplify3(ptr %dst) {45; CHECK-LABEL: @test_simplify3(46; CHECK-NEXT: store i8 0, ptr [[DST:%.*]], align 147; CHECK-NEXT: ret void48;49 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @null_hello)50 ret void51}52 53; Check sprintf(dst, "%c", chr) -> *(ptr)dst = chr; *((ptr)dst + 1) = 0.54 55define void @test_simplify4(ptr %dst) {56; CHECK-LABEL: @test_simplify4(57; CHECK-NEXT: store i8 104, ptr [[DST:%.*]], align 158; CHECK-NEXT: [[NUL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i32 159; CHECK-NEXT: store i8 0, ptr [[NUL]], align 160; CHECK-NEXT: ret void61;62 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_c, i8 104)63 ret void64}65 66; Check sprintf(dst, "%s", str) -> strcpy(dst, "%s", str) if result is unused.67 68define void @test_simplify5(ptr %dst, ptr %str) {69; CHECK-LABEL: @test_simplify5(70; CHECK-NEXT: [[STRCPY:%.*]] = call ptr @strcpy(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) [[STR:%.*]])71; CHECK-NEXT: ret void72;73 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr %str)74 ret void75}76 77; Check sprintf(dst, format, ...) -> siprintf(str, format, ...) if no floating.78 79define void @test_simplify6(ptr %dst) {80; CHECK-IPRINTF-LABEL: @test_simplify6(81; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (ptr, ptr, ...) @siprintf(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) @percent_d, i32 187)82; CHECK-IPRINTF-NEXT: ret void83;84; NOSTPCPY-LABEL: @test_simplify6(85; NOSTPCPY-NEXT: [[TMP1:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) @percent_d, i32 187)86; NOSTPCPY-NEXT: ret void87;88 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_d, i32 187)89 ret void90}91 92; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen(str) + 1, 1).93 94define i32 @test_simplify7(ptr %dst, ptr %str) {95; WITHSTPCPY-LABEL: @test_simplify7(96; WITHSTPCPY-NEXT: [[STPCPY:%.*]] = call ptr @stpcpy(ptr [[DST:%.*]], ptr [[STR:%.*]])97; WITHSTPCPY-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[STPCPY]] to i3298; WITHSTPCPY-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DST]] to i3299; WITHSTPCPY-NEXT: [[R:%.*]] = sub i32 [[TMP1]], [[TMP2]]100; WITHSTPCPY-NEXT: ret i32 [[R]]101;102; NOSTPCPY-LABEL: @test_simplify7(103; NOSTPCPY-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]])104; NOSTPCPY-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1105; NOSTPCPY-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr nonnull align 1 [[STR]], i32 [[LENINC]], i1 false)106; NOSTPCPY-NEXT: ret i32 [[STRLEN]]107;108 %r = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr %str)109 ret i32 %r110}111 112; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen(str) + 1, 1).113define i32 @test_simplify8(ptr %dst) {114; CHECK-LABEL: @test_simplify8(115; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(13) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(13) @hello_world, i32 13, i1 false)116; CHECK-NEXT: ret i32 12117;118 %r = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr @hello_world)119 ret i32 %r120}121 122; Check sprintf(dst, "%s", str) -> stpcpy(dest, str) - dest123 124define i32 @test_simplify9(ptr %dst, ptr %str) {125; WITHSTPCPY-LABEL: @test_simplify9(126; WITHSTPCPY-NEXT: [[STPCPY:%.*]] = call ptr @stpcpy(ptr [[DST:%.*]], ptr [[STR:%.*]])127; WITHSTPCPY-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[STPCPY]] to i32128; WITHSTPCPY-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DST]] to i32129; WITHSTPCPY-NEXT: [[R:%.*]] = sub i32 [[TMP1]], [[TMP2]]130; WITHSTPCPY-NEXT: ret i32 [[R]]131;132; NOSTPCPY-LABEL: @test_simplify9(133; NOSTPCPY-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]])134; NOSTPCPY-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1135; NOSTPCPY-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr nonnull align 1 [[STR]], i32 [[LENINC]], i1 false)136; NOSTPCPY-NEXT: ret i32 [[STRLEN]]137;138 %r = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr %str)139 ret i32 %r140}141 142define void @test_no_simplify1(ptr %dst) {143; CHECK-LABEL: @test_no_simplify1(144; CHECK-NEXT: [[TMP1:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) @percent_f, double 1.870000e+00)145; CHECK-NEXT: ret void146;147 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_f, double 1.87)148 ret void149}150 151define void @test_no_simplify2(ptr %dst, ptr %fmt, double %d) {152; CHECK-LABEL: @test_no_simplify2(153; CHECK-NEXT: [[TMP1:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])154; CHECK-NEXT: ret void155;156 call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr %fmt, double %d)157 ret void158}159 160define i32 @test_no_simplify3(ptr %dst, ptr %str) minsize {161; WITHSTPCPY-LABEL: @test_no_simplify3(162; WITHSTPCPY-NEXT: [[STPCPY:%.*]] = call ptr @stpcpy(ptr [[DST:%.*]], ptr [[STR:%.*]])163; WITHSTPCPY-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[STPCPY]] to i32164; WITHSTPCPY-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DST]] to i32165; WITHSTPCPY-NEXT: [[R:%.*]] = sub i32 [[TMP1]], [[TMP2]]166; WITHSTPCPY-NEXT: ret i32 [[R]]167;168; NOSTPCPY-LABEL: @test_no_simplify3(169; NOSTPCPY-NEXT: [[R:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) @percent_s, ptr [[STR:%.*]])170; NOSTPCPY-NEXT: ret i32 [[R]]171;172 %r = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr %str)173 ret i32 %r174}175