133 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2;3; Verify that snprintf calls with a constant size not exceeding INT_MAX4; and constant format string with no formatting directives are transformed5; into memcpy. Also verify that a size in excess of INT_MAX prevents6; the transformation.7;8; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s -check-prefixes=ANY,BE9; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s -check-prefixes=ANY,LE10 11@s = constant [4 x i8] c"123\00"12 13@adst = external global [0 x ptr]14@asiz = external global [0 x i32]15 16declare i32 @snprintf(ptr, i64, ptr, ...)17 18 19; Verify that all snprintf calls with a bound between INT_MAX and down20; to 0 are transformed to memcpy.21 22define void @fold_snprintf_fmt() {23; BE-LABEL: @fold_snprintf_fmt(24; BE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 17179869176), align 825; BE-NEXT: store i32 825373440, ptr [[PDIMAX]], align 126; BE-NEXT: store i32 3, ptr @asiz, align 427; BE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 40), align 828; BE-NEXT: store i32 825373440, ptr [[PD5]], align 129; BE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 20), align 430; BE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 32), align 831; BE-NEXT: store i32 825373440, ptr [[PD4]], align 132; BE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 16), align 433; BE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 24), align 834; BE-NEXT: store i16 12594, ptr [[PD3]], align 135; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds nuw i8, ptr [[PD3]], i64 236; BE-NEXT: store i8 0, ptr [[ENDPTR]], align 137; BE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 12), align 438; BE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 16), align 839; BE-NEXT: store i8 49, ptr [[PD2]], align 140; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[PD2]], i64 141; BE-NEXT: store i8 0, ptr [[ENDPTR1]], align 142; BE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 8), align 443; BE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 8), align 844; BE-NEXT: store i8 0, ptr [[PD1]], align 145; BE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 4), align 446; BE-NEXT: store i32 3, ptr @asiz, align 447; BE-NEXT: ret void48;49; LE-LABEL: @fold_snprintf_fmt(50; LE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 17179869176), align 851; LE-NEXT: store i32 3355185, ptr [[PDIMAX]], align 152; LE-NEXT: store i32 3, ptr @asiz, align 453; LE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 40), align 854; LE-NEXT: store i32 3355185, ptr [[PD5]], align 155; LE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 20), align 456; LE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 32), align 857; LE-NEXT: store i32 3355185, ptr [[PD4]], align 158; LE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 16), align 459; LE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 24), align 860; LE-NEXT: store i16 12849, ptr [[PD3]], align 161; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds nuw i8, ptr [[PD3]], i64 262; LE-NEXT: store i8 0, ptr [[ENDPTR]], align 163; LE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 12), align 464; LE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 16), align 865; LE-NEXT: store i8 49, ptr [[PD2]], align 166; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[PD2]], i64 167; LE-NEXT: store i8 0, ptr [[ENDPTR1]], align 168; LE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 8), align 469; LE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 8), align 870; LE-NEXT: store i8 0, ptr [[PD1]], align 171; LE-NEXT: store i32 3, ptr getelementptr (i8, ptr @asiz, i64 4), align 472; LE-NEXT: store i32 3, ptr @asiz, align 473; LE-NEXT: ret void74;75 76 %pdimax = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 2147483647)77 %nimax = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pdimax, i64 2147483647, ptr @s)78 store i32 %nimax, ptr @asiz79 80 %pd5 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 5)81 %n5 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd5, i64 5, ptr @s)82 store i32 %n5, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 5)83 84 %pd4 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 4)85 %n4 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd4, i64 4, ptr @s)86 store i32 %n4, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 4)87 88 %pd3 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 3)89 %n3 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd3, i64 3, ptr @s)90 store i32 %n3, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 3)91 92 %pd2 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 2)93 %n2 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd2, i64 2, ptr @s)94 store i32 %n2, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 2)95 96 %pd1 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 1)97 %n1 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd1, i64 1, ptr @s)98 store i32 %n1, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 1)99 100 %pd0 = load ptr, ptr @adst101 %n0 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pd0, i64 0, ptr @s)102 store i32 %n0, ptr @asiz103 104 ret void105}106 107 108; Verify that snprintf calls with a bound greater than INT_MAX are not109; transformed. POSIX requires implementations to set errno to EOVERFLOW110; so such calls could be folded to just that followed by returning -1.111 112define void @call_snprintf_fmt_ximax() {113; ANY-LABEL: @call_snprintf_fmt_ximax(114; ANY-NEXT: [[PDM1:%.*]] = load ptr, ptr getelementptr (i8, ptr @adst, i64 8), align 8115; ANY-NEXT: [[NM1:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr noundef nonnull dereferenceable(1) [[PDM1]], i64 -1, ptr nonnull @s)116; ANY-NEXT: store i32 [[NM1]], ptr getelementptr (i8, ptr @asiz, i64 4), align 4117; ANY-NEXT: [[PDIMAXP1:%.*]] = load ptr, ptr @adst, align 8118; ANY-NEXT: [[NIMAXP1:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr noundef nonnull dereferenceable(1) [[PDIMAXP1]], i64 2147483648, ptr nonnull @s)119; ANY-NEXT: store i32 [[NIMAXP1]], ptr @asiz, align 4120; ANY-NEXT: ret void121;122 123 %pdm1 = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 1)124 %nm1 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pdm1, i64 -1, ptr @s)125 store i32 %nm1, ptr getelementptr ([0 x i32], ptr @asiz, i32 0, i32 1)126 127 %pdimaxp1 = load ptr, ptr @adst128 %nimaxp1 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %pdimaxp1, i64 2147483648, ptr @s)129 store i32 %nimaxp1, ptr @asiz130 131 ret void132}133