1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Test that the printf library call simplifier works correctly. 3; 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5; RUN: opt < %s -mtriple xcore-xmos-elf -passes=instcombine -S | FileCheck %s -check-prefix=CHECK-IPRINTF 6 7target 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" 8 9@hello_world = constant [13 x i8] c"hello world\0A\00" 10@h = constant [2 x i8] c"h\00" 11@h2 = constant [3 x i8] c"%%\00" 12@percent = constant [2 x i8] c"%\00" 13@percent_c = constant [3 x i8] c"%c\00" 14@percent_d = constant [3 x i8] c"%d\00" 15@percent_f = constant [3 x i8] c"%f\00" 16@percent_s = constant [4 x i8] c"%s\0A\00" 17@empty = constant [1 x i8] c"\00" 18 19declare i32 @printf(ptr, ...) 20 21; Check printf("") -> noop. 22 23define void @test_simplify1() { 24; CHECK-LABEL: @test_simplify1( 25; CHECK-NEXT: ret void 26; 27; CHECK-IPRINTF-LABEL: @test_simplify1( 28; CHECK-IPRINTF-NEXT: ret void 29; 30 call i32 (ptr, ...) @printf(ptr @empty) 31 ret void 32} 33 34; Check printf("x") -> putchar('x'), even for '%'. 35 36define void @test_simplify2() { 37; CHECK-LABEL: @test_simplify2( 38; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104) 39; CHECK-NEXT: ret void 40; 41; CHECK-IPRINTF-LABEL: @test_simplify2( 42; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104) 43; CHECK-IPRINTF-NEXT: ret void 44; 45 call i32 (ptr, ...) @printf(ptr @h) 46 ret void 47} 48 49; Special case: printf("%%") -> putchar('%'). 50 51define void @test_simplify2b() { 52; CHECK-LABEL: @test_simplify2b( 53; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37) 54; CHECK-NEXT: ret void 55; 56; CHECK-IPRINTF-LABEL: @test_simplify2b( 57; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37) 58; CHECK-IPRINTF-NEXT: ret void 59; 60 call i32 (ptr, ...) @printf(ptr @h2) 61 ret void 62} 63 64define void @test_simplify3() { 65; CHECK-LABEL: @test_simplify3( 66; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37) 67; CHECK-NEXT: ret void 68; 69; CHECK-IPRINTF-LABEL: @test_simplify3( 70; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 37) 71; CHECK-IPRINTF-NEXT: ret void 72; 73 call i32 (ptr, ...) @printf(ptr @percent) 74 ret void 75} 76 77; Check printf("foo\n") -> puts("foo"). 78 79define void @test_simplify4() { 80; CHECK-LABEL: @test_simplify4( 81; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(ptr nonnull dereferenceable(1) @str) 82; CHECK-NEXT: ret void 83; 84; CHECK-IPRINTF-LABEL: @test_simplify4( 85; CHECK-IPRINTF-NEXT: [[PUTS:%.*]] = call i32 @puts(ptr nonnull dereferenceable(1) @str) 86; CHECK-IPRINTF-NEXT: ret void 87; 88 call i32 (ptr, ...) @printf(ptr @hello_world) 89 ret void 90} 91 92; Check printf("%c", chr) -> putchar(chr). 93 94define void @test_simplify5() { 95; CHECK-LABEL: @test_simplify5( 96; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104) 97; CHECK-NEXT: ret void 98; 99; CHECK-IPRINTF-LABEL: @test_simplify5( 100; CHECK-IPRINTF-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 104) 101; CHECK-IPRINTF-NEXT: ret void 102; 103 call i32 (ptr, ...) @printf(ptr @percent_c, i8 104) 104 ret void 105} 106 107; Check printf("%s\n", str) -> puts(str). 108 109define void @test_simplify6() { 110; CHECK-LABEL: @test_simplify6( 111; CHECK-NEXT: [[PUTS:%.*]] = call i32 @puts(ptr nonnull dereferenceable(1) @hello_world) 112; CHECK-NEXT: ret void 113; 114; CHECK-IPRINTF-LABEL: @test_simplify6( 115; CHECK-IPRINTF-NEXT: [[PUTS:%.*]] = call i32 @puts(ptr nonnull dereferenceable(1) @hello_world) 116; CHECK-IPRINTF-NEXT: ret void 117; 118 call i32 (ptr, ...) @printf(ptr @percent_s, ptr @hello_world) 119 ret void 120} 121 122; Check printf(format, ...) -> iprintf(format, ...) if no floating point. 123 124define void @test_simplify7() { 125; CHECK-LABEL: @test_simplify7( 126; CHECK-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @percent_d, i32 187) 127; CHECK-NEXT: ret void 128; 129; CHECK-IPRINTF-LABEL: @test_simplify7( 130; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @iprintf(ptr noundef nonnull dereferenceable(1) @percent_d, i32 187) 131; CHECK-IPRINTF-NEXT: ret void 132; 133 call i32 (ptr, ...) @printf(ptr @percent_d, i32 187) 134 ret void 135} 136 137define void @test_no_simplify1() { 138; CHECK-LABEL: @test_no_simplify1( 139; CHECK-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @percent_f, double 1.870000e+00) 140; CHECK-NEXT: ret void 141; 142; CHECK-IPRINTF-LABEL: @test_no_simplify1( 143; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @percent_f, double 1.870000e+00) 144; CHECK-IPRINTF-NEXT: ret void 145; 146 call i32 (ptr, ...) @printf(ptr @percent_f, double 1.87) 147 ret void 148} 149 150define void @test_no_simplify2(ptr %fmt, double %d) { 151; CHECK-LABEL: @test_no_simplify2( 152; CHECK-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]]) 153; CHECK-NEXT: ret void 154; 155; CHECK-IPRINTF-LABEL: @test_no_simplify2( 156; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]]) 157; CHECK-IPRINTF-NEXT: ret void 158; 159 call i32 (ptr, ...) @printf(ptr %fmt, double %d) 160 ret void 161} 162 163define i32 @test_no_simplify3() { 164; CHECK-LABEL: @test_no_simplify3( 165; CHECK-NEXT: [[RET:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @h) 166; CHECK-NEXT: ret i32 [[RET]] 167; 168; CHECK-IPRINTF-LABEL: @test_no_simplify3( 169; CHECK-IPRINTF-NEXT: [[RET:%.*]] = call i32 (ptr, ...) @iprintf(ptr noundef nonnull dereferenceable(1) @h) 170; CHECK-IPRINTF-NEXT: ret i32 [[RET]] 171; 172 %ret = call i32 (ptr, ...) @printf(ptr @h) 173 ret i32 %ret 174} 175