1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 5 6@a = common global [60 x i8] zeroinitializer, align 1 7@b = common global [60 x i8] zeroinitializer, align 1 8@.str = private constant [12 x i8] c"abcdefghijk\00" 9 10%struct.__va_list_tag = type { i32, i32, ptr, ptr } 11 12define ptr @test_memccpy() { 13; CHECK-LABEL: @test_memccpy( 14; CHECK-NEXT: [[MEMCCPY:%.*]] = call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60) 15; CHECK-NEXT: ret ptr [[MEMCCPY]] 16; 17 %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1) 18 ret ptr %ret 19} 20 21define ptr @test_not_memccpy() { 22; CHECK-LABEL: @test_not_memccpy( 23; CHECK-NEXT: [[RET:%.*]] = call ptr @__memccpy_chk(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60, i64 59) 24; CHECK-NEXT: ret ptr [[RET]] 25; 26 %ret = call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 59) 27 ret ptr %ret 28} 29 30define ptr @test_memccpy_tail() { 31; CHECK-LABEL: @test_memccpy_tail( 32; CHECK-NEXT: [[MEMCCPY:%.*]] = tail call ptr @memccpy(ptr nonnull @a, ptr nonnull @b, i32 0, i64 60) 33; CHECK-NEXT: ret ptr [[MEMCCPY]] 34; 35 %ret = tail call ptr @__memccpy_chk(ptr @a, ptr @b, i32 0, i64 60, i64 -1) 36 ret ptr %ret 37} 38 39define ptr @test_mempcpy() { 40; CHECK-LABEL: @test_mempcpy( 41; 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) 42; CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr @a, i64 15) 43; 44 %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1) 45 ret ptr %ret 46} 47 48define ptr @test_not_mempcpy() { 49; CHECK-LABEL: @test_not_mempcpy( 50; CHECK-NEXT: [[RET:%.*]] = call ptr @__mempcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 60, i64 59) 51; CHECK-NEXT: ret ptr [[RET]] 52; 53 %ret = call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 60, i64 59) 54 ret ptr %ret 55} 56 57define ptr @test_mempcpy_tail() { 58; CHECK-LABEL: @test_mempcpy_tail( 59; 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) 60; CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr @a, i64 15) 61; 62 %ret = tail call ptr @__mempcpy_chk(ptr @a, ptr @b, i64 15, i64 -1) 63 ret ptr %ret 64} 65 66define i32 @test_snprintf() { 67; CHECK-LABEL: @test_snprintf( 68; CHECK-NEXT: [[SNPRINTF:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b) 69; CHECK-NEXT: ret i32 [[SNPRINTF]] 70; 71 %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b) 72 ret i32 %ret 73} 74 75define i32 @test_not_snprintf() { 76; CHECK-LABEL: @test_not_snprintf( 77; CHECK-NEXT: [[RET:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 0, i64 59, ptr nonnull @b) 78; CHECK-NEXT: [[IGN:%.*]] = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr nonnull @a, i64 60, i32 1, i64 -1, ptr nonnull @b) 79; CHECK-NEXT: ret i32 [[RET]] 80; 81 %ret = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 59, ptr @b) 82 %ign = call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 1, i64 -1, ptr @b) 83 ret i32 %ret 84} 85 86define i32 @test_snprintf_tail() { 87; CHECK-LABEL: @test_snprintf_tail( 88; CHECK-NEXT: [[SNPRINTF:%.*]] = tail call i32 (ptr, i64, ptr, ...) @snprintf(ptr nonnull dereferenceable(1) @a, i64 60, ptr nonnull @b) 89; CHECK-NEXT: ret i32 [[SNPRINTF]] 90; 91 %ret = tail call i32 (ptr, i64, i32, i64, ptr, ...) @__snprintf_chk(ptr @a, i64 60, i32 0, i64 -1, ptr @b) 92 ret i32 %ret 93} 94 95define i32 @test_sprintf() { 96; CHECK-LABEL: @test_sprintf( 97; CHECK-NEXT: [[SPRINTF:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b) 98; CHECK-NEXT: ret i32 [[SPRINTF]] 99; 100 %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b) 101 ret i32 %ret 102} 103 104define i32 @test_not_sprintf() { 105; CHECK-LABEL: @test_not_sprintf( 106; CHECK-NEXT: [[RET:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 0, i64 59, ptr nonnull @b) 107; CHECK-NEXT: [[IGNORED:%.*]] = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b) 108; CHECK-NEXT: ret i32 [[RET]] 109; 110 %ret = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 59, ptr @b) 111 %ignored = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 1, i64 -1, ptr @b) 112 ret i32 %ret 113} 114 115define i32 @test_sprintf_tail() { 116; CHECK-LABEL: @test_sprintf_tail( 117; CHECK-NEXT: [[SPRINTF:%.*]] = tail call i32 (ptr, ptr, ...) @sprintf(ptr nonnull dereferenceable(1) @a, ptr nonnull dereferenceable(1) @b) 118; CHECK-NEXT: ret i32 [[SPRINTF]] 119; 120 %ret = tail call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr @a, i32 0, i64 -1, ptr @b) 121 ret i32 %ret 122} 123 124define ptr @test_strcat() { 125; CHECK-LABEL: @test_strcat( 126; CHECK-NEXT: [[STRCAT:%.*]] = call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) 127; CHECK-NEXT: ret ptr @a 128; 129 %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1) 130 ret ptr %ret 131} 132 133define ptr @test_not_strcat() { 134; CHECK-LABEL: @test_not_strcat( 135; CHECK-NEXT: [[RET:%.*]] = call ptr @__strcat_chk(ptr nonnull @a, ptr nonnull @b, i64 0) 136; CHECK-NEXT: ret ptr [[RET]] 137; 138 %ret = call ptr @__strcat_chk(ptr @a, ptr @b, i64 0) 139 ret ptr %ret 140} 141 142define ptr @test_strcat_tail() { 143; CHECK-LABEL: @test_strcat_tail( 144; CHECK-NEXT: [[STRCAT:%.*]] = tail call ptr @strcat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) 145; CHECK-NEXT: ret ptr @a 146; 147 %ret = tail call ptr @__strcat_chk(ptr @a, ptr @b, i64 -1) 148 ret ptr %ret 149} 150 151define i64 @test_strlcat() { 152; CHECK-LABEL: @test_strlcat( 153; CHECK-NEXT: [[STRLCAT:%.*]] = call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22) 154; CHECK-NEXT: ret i64 [[STRLCAT]] 155; 156 %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1) 157 ret i64 %ret 158} 159 160define i64 @test_not_strlcat() { 161; CHECK-LABEL: @test_not_strlcat( 162; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 0) 163; CHECK-NEXT: ret i64 [[RET]] 164; 165 %ret = call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 0) 166 ret i64 %ret 167} 168 169define i64 @test_strlcat_tail() { 170; CHECK-LABEL: @test_strlcat_tail( 171; CHECK-NEXT: [[STRLCAT:%.*]] = tail call i64 @strlcat(ptr nonnull @a, ptr nonnull @b, i64 22) 172; CHECK-NEXT: ret i64 [[STRLCAT]] 173; 174 %ret = tail call i64 @__strlcat_chk(ptr @a, ptr @b, i64 22, i64 -1) 175 ret i64 %ret 176} 177 178define ptr @test_strncat() { 179; CHECK-LABEL: @test_strncat( 180; CHECK-NEXT: [[STRNCAT:%.*]] = call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) 181; CHECK-NEXT: ret ptr @a 182; 183 %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1) 184 ret ptr %ret 185} 186 187define ptr @test_not_strncat() { 188; CHECK-LABEL: @test_not_strncat( 189; CHECK-NEXT: [[RET:%.*]] = call ptr @__strncat_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 3) 190; CHECK-NEXT: ret ptr [[RET]] 191; 192 %ret = call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 3) 193 ret ptr %ret 194} 195 196define ptr @test_strncat_tail() { 197; CHECK-LABEL: @test_strncat_tail( 198; CHECK-NEXT: [[STRNCAT:%.*]] = tail call ptr @strncat(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) 199; CHECK-NEXT: ret ptr @a 200; 201 %ret = tail call ptr @__strncat_chk(ptr @a, ptr @b, i64 22, i64 -1) 202 ret ptr %ret 203} 204 205define i64 @test_strlcpy() { 206; CHECK-LABEL: @test_strlcpy( 207; CHECK-NEXT: [[STRLCPY:%.*]] = call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) 208; CHECK-NEXT: ret i64 [[STRLCPY]] 209; 210 %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1) 211 ret i64 %ret 212} 213 214define i64 @test_not_strlcpy() { 215; CHECK-LABEL: @test_not_strlcpy( 216; CHECK-NEXT: [[RET:%.*]] = call i64 @__strlcpy_chk(ptr nonnull @a, ptr nonnull @b, i64 22, i64 2) 217; CHECK-NEXT: ret i64 [[RET]] 218; 219 %ret = call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 2) 220 ret i64 %ret 221} 222 223define i64 @test_strlcpy_tail() { 224; CHECK-LABEL: @test_strlcpy_tail( 225; CHECK-NEXT: [[STRLCPY:%.*]] = tail call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i64 22) 226; CHECK-NEXT: ret i64 [[STRLCPY]] 227; 228 %ret = tail call i64 @__strlcpy_chk(ptr @a, ptr @b, i64 22, i64 -1) 229 ret i64 %ret 230} 231 232define i32 @test_vsnprintf() { 233; CHECK-LABEL: @test_vsnprintf( 234; CHECK-NEXT: [[VSNPRINTF:%.*]] = call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null) 235; CHECK-NEXT: ret i32 [[VSNPRINTF]] 236; 237 ; ret i32 238 %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null) 239 ret i32 %ret 240} 241 242define i32 @test_not_vsnprintf() { 243; CHECK-LABEL: @test_not_vsnprintf( 244; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 0, i64 3, ptr nonnull @b, ptr null) 245; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsnprintf_chk(ptr nonnull @a, i64 4, i32 1, i64 -1, ptr nonnull @b, ptr null) 246; CHECK-NEXT: ret i32 [[RET]] 247; 248 ; ret i32 249 %ret = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 3, ptr @b, ptr null) 250 %ign = call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 1, i64 -1, ptr @b, ptr null) 251 ret i32 %ret 252} 253 254define i32 @test_vsnprintf_tail() { 255; CHECK-LABEL: @test_vsnprintf_tail( 256; CHECK-NEXT: [[VSNPRINTF:%.*]] = tail call i32 @vsnprintf(ptr nonnull @a, i64 4, ptr nonnull @b, ptr null) 257; CHECK-NEXT: ret i32 [[VSNPRINTF]] 258; 259 ; ret i32 260 %ret = tail call i32 @__vsnprintf_chk(ptr @a, i64 4, i32 0, i64 -1, ptr @b, ptr null) 261 ret i32 %ret 262} 263 264define i32 @test_vsprintf() { 265; CHECK-LABEL: @test_vsprintf( 266; CHECK-NEXT: [[VSPRINTF:%.*]] = call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null) 267; CHECK-NEXT: ret i32 [[VSPRINTF]] 268; 269 ; ret i32 270 %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null) 271 ret i32 %ret 272} 273 274define i32 @test_not_vsprintf() { 275; CHECK-LABEL: @test_not_vsprintf( 276; CHECK-NEXT: [[RET:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 0, i64 3, ptr nonnull @b, ptr null) 277; CHECK-NEXT: [[IGN:%.*]] = call i32 @__vsprintf_chk(ptr nonnull @a, i32 1, i64 -1, ptr nonnull @b, ptr null) 278; CHECK-NEXT: ret i32 [[RET]] 279; 280 ; ret i32 281 %ret = call i32 @__vsprintf_chk(ptr @a, i32 0, i64 3, ptr @b, ptr null) 282 %ign = call i32 @__vsprintf_chk(ptr @a, i32 1, i64 -1, ptr @b, ptr null) 283 ret i32 %ret 284} 285 286define i32 @test_vsprintf_tail() { 287; CHECK-LABEL: @test_vsprintf_tail( 288; CHECK-NEXT: [[VSPRINTF:%.*]] = tail call i32 @vsprintf(ptr nonnull @a, ptr nonnull @b, ptr null) 289; CHECK-NEXT: ret i32 [[VSPRINTF]] 290; 291 ; ret i32 292 %ret = tail call i32 @__vsprintf_chk(ptr @a, i32 0, i64 -1, ptr @b, ptr null) 293 ret i32 %ret 294} 295 296declare ptr @__mempcpy_chk(ptr, ptr, i64, i64) 297declare ptr @__memccpy_chk(ptr, ptr, i32, i64, i64) 298declare i32 @__snprintf_chk(ptr, i64, i32, i64, ptr, ...) 299declare i32 @__sprintf_chk(ptr, i32, i64, ptr, ...) 300declare ptr @__strcat_chk(ptr, ptr, i64) 301declare i64 @__strlcat_chk(ptr, ptr, i64, i64) 302declare ptr @__strncat_chk(ptr, ptr, i64, i64) 303declare i64 @__strlcpy_chk(ptr, ptr, i64, i64) 304declare i32 @__vsnprintf_chk(ptr, i64, i32, i64, ptr, ptr) 305declare i32 @__vsprintf_chk(ptr, i32, i64, ptr, ptr) 306