384 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc"5declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"6declare noalias ptr @realloc(ptr nocapture, i64) allockind("realloc") allocsize(1) "alloc-family"="malloc"7declare noalias nonnull ptr @_Znam(i64) ; throwing version of 'new'8declare noalias nonnull ptr @_Znwm(i64) ; throwing version of 'new'9declare noalias ptr @strdup(ptr)10declare noalias ptr @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1) "alloc-family"="malloc"11declare noalias align 16 ptr @memalign(i64 allocalign, i64) allocsize(1)12; new[](unsigned int, align_val_t)13declare noalias ptr @_ZnamSt11align_val_t(i64 %size, i64 %align)14 15declare ptr @my_malloc(i64) allocsize(0)16declare ptr @my_calloc(i64, i64) allocsize(0, 1)17 18@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 119 20define noalias ptr @malloc_nonconstant_size(i64 %n) {21; CHECK-LABEL: @malloc_nonconstant_size(22; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 [[N:%.*]])23; CHECK-NEXT: ret ptr [[CALL]]24;25 %call = tail call noalias ptr @malloc(i64 %n)26 ret ptr %call27}28 29define noalias ptr @malloc_constant_size() {30; CHECK-LABEL: @malloc_constant_size(31; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)32; CHECK-NEXT: ret ptr [[CALL]]33;34 %call = tail call noalias ptr @malloc(i64 40)35 ret ptr %call36}37 38define noalias ptr @aligned_alloc_constant_size() {39; CHECK-LABEL: @aligned_alloc_constant_size(40; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @aligned_alloc(i64 32, i64 512)41; CHECK-NEXT: ret ptr [[CALL]]42;43 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 512)44 ret ptr %call45}46 47define noalias ptr @aligned_alloc_unknown_size_nonzero(i1 %c) {48; CHECK-LABEL: @aligned_alloc_unknown_size_nonzero(49; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 12850; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])51; CHECK-NEXT: ret ptr [[CALL]]52;53 %size = select i1 %c, i64 64, i64 12854 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)55 ret ptr %call56}57 58define noalias ptr @aligned_alloc_unknown_size_possibly_zero(i1 %c) {59; CHECK-LABEL: @aligned_alloc_unknown_size_possibly_zero(60; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 061; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])62; CHECK-NEXT: ret ptr [[CALL]]63;64 %size = select i1 %c, i64 64, i64 065 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)66 ret ptr %call67}68 69define noalias ptr @aligned_alloc_unknown_align(i64 %align) {70; CHECK-LABEL: @aligned_alloc_unknown_align(71; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 128)72; CHECK-NEXT: ret ptr [[CALL]]73;74 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 128)75 ret ptr %call76}77 78declare noalias ptr @foo(ptr, ptr, ptr)79 80define noalias ptr @aligned_alloc_dynamic_args(i64 %align, i64 %size) {81; CHECK-LABEL: @aligned_alloc_dynamic_args(82; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 1024)83; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 0, i64 1024)84; CHECK-NEXT: [[CALL_2:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE:%.*]])85; CHECK-NEXT: [[TMP1:%.*]] = call ptr @foo(ptr [[CALL]], ptr [[CALL_1]], ptr [[CALL_2]])86; CHECK-NEXT: ret ptr [[CALL]]87;88 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 1024)89 %call_1 = tail call noalias ptr @aligned_alloc(i64 0, i64 1024)90 %call_2 = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)91 92 call ptr @foo(ptr %call, ptr %call_1, ptr %call_2)93 ret ptr %call94}95 96define noalias ptr @memalign_constant_size() {97; CHECK-LABEL: @memalign_constant_size(98; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @memalign(i64 32, i64 512)99; CHECK-NEXT: ret ptr [[CALL]]100;101 %call = tail call noalias ptr @memalign(i64 32, i64 512)102 ret ptr %call103}104 105define noalias ptr @memalign_unknown_size_nonzero(i1 %c) {106; CHECK-LABEL: @memalign_unknown_size_nonzero(107; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128108; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])109; CHECK-NEXT: ret ptr [[CALL]]110;111 %size = select i1 %c, i64 64, i64 128112 %call = tail call noalias ptr @memalign(i64 32, i64 %size)113 ret ptr %call114}115 116define noalias ptr @memalign_unknown_size_possibly_zero(i1 %c) {117; CHECK-LABEL: @memalign_unknown_size_possibly_zero(118; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0119; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])120; CHECK-NEXT: ret ptr [[CALL]]121;122 %size = select i1 %c, i64 64, i64 0123 %call = tail call noalias ptr @memalign(i64 32, i64 %size)124 ret ptr %call125}126 127define noalias ptr @memalign_unknown_align(i64 %align) {128; CHECK-LABEL: @memalign_unknown_align(129; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @memalign(i64 [[ALIGN:%.*]], i64 128)130; CHECK-NEXT: ret ptr [[CALL]]131;132 %call = tail call noalias ptr @memalign(i64 %align, i64 128)133 ret ptr %call134}135 136define noalias ptr @malloc_constant_size2() {137; CHECK-LABEL: @malloc_constant_size2(138; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)139; CHECK-NEXT: ret ptr [[CALL]]140;141 %call = tail call noalias dereferenceable_or_null(80) ptr @malloc(i64 40)142 ret ptr %call143}144 145define noalias ptr @malloc_constant_size3() {146; CHECK-LABEL: @malloc_constant_size3(147; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable(80) dereferenceable_or_null(40) ptr @malloc(i64 40)148; CHECK-NEXT: ret ptr [[CALL]]149;150 %call = tail call noalias dereferenceable(80) ptr @malloc(i64 40)151 ret ptr %call152}153 154define noalias ptr @malloc_constant_zero_size() {155; CHECK-LABEL: @malloc_constant_zero_size(156; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 0)157; CHECK-NEXT: ret ptr [[CALL]]158;159 %call = tail call noalias ptr @malloc(i64 0)160 ret ptr %call161}162 163define noalias ptr @realloc_nonconstant_size(ptr %p, i64 %n) {164; CHECK-LABEL: @realloc_nonconstant_size(165; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 [[N:%.*]])166; CHECK-NEXT: ret ptr [[CALL]]167;168 %call = tail call noalias ptr @realloc(ptr %p, i64 %n)169 ret ptr %call170}171 172define noalias ptr @realloc_constant_zero_size(ptr %p) {173; CHECK-LABEL: @realloc_constant_zero_size(174; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 0)175; CHECK-NEXT: ret ptr [[CALL]]176;177 %call = tail call noalias ptr @realloc(ptr %p, i64 0)178 ret ptr %call179}180 181define noalias ptr @realloc_constant_size(ptr %p) {182; CHECK-LABEL: @realloc_constant_size(183; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @realloc(ptr [[P:%.*]], i64 40)184; CHECK-NEXT: ret ptr [[CALL]]185;186 %call = tail call noalias ptr @realloc(ptr %p, i64 40)187 ret ptr %call188}189 190define noalias ptr @calloc_nonconstant_size(i64 %n) {191; CHECK-LABEL: @calloc_nonconstant_size(192; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 [[N:%.*]])193; CHECK-NEXT: ret ptr [[CALL]]194;195 %call = tail call noalias ptr @calloc(i64 1, i64 %n)196 ret ptr %call197}198 199define noalias ptr @calloc_nonconstant_size2(i64 %n) {200; CHECK-LABEL: @calloc_nonconstant_size2(201; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)202; CHECK-NEXT: ret ptr [[CALL]]203;204 %call = tail call noalias ptr @calloc(i64 %n, i64 0)205 ret ptr %call206}207 208define noalias ptr @calloc_nonconstant_size3(i64 %n) {209; CHECK-LABEL: @calloc_nonconstant_size3(210; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 [[N]])211; CHECK-NEXT: ret ptr [[CALL]]212;213 %call = tail call noalias ptr @calloc(i64 %n, i64 %n)214 ret ptr %call215}216 217define noalias ptr @calloc_constant_zero_size() {218; CHECK-LABEL: @calloc_constant_zero_size(219; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 0)220; CHECK-NEXT: ret ptr [[CALL]]221;222 %call = tail call noalias ptr @calloc(i64 0, i64 0)223 ret ptr %call224}225 226define noalias ptr @calloc_constant_zero_size2(i64 %n) {227; CHECK-LABEL: @calloc_constant_zero_size2(228; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)229; CHECK-NEXT: ret ptr [[CALL]]230;231 %call = tail call noalias ptr @calloc(i64 %n, i64 0)232 ret ptr %call233}234 235 236define noalias ptr @calloc_constant_zero_size3(i64 %n) {237; CHECK-LABEL: @calloc_constant_zero_size3(238; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 [[N:%.*]])239; CHECK-NEXT: ret ptr [[CALL]]240;241 %call = tail call noalias ptr @calloc(i64 0, i64 %n)242 ret ptr %call243}244 245define noalias ptr @calloc_constant_zero_size4(i64 %n) {246; CHECK-LABEL: @calloc_constant_zero_size4(247; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 1)248; CHECK-NEXT: ret ptr [[CALL]]249;250 %call = tail call noalias ptr @calloc(i64 0, i64 1)251 ret ptr %call252}253 254define noalias ptr @calloc_constant_zero_size5(i64 %n) {255; CHECK-LABEL: @calloc_constant_zero_size5(256; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 0)257; CHECK-NEXT: ret ptr [[CALL]]258;259 %call = tail call noalias ptr @calloc(i64 1, i64 0)260 ret ptr %call261}262 263define noalias ptr @calloc_constant_size() {264; CHECK-LABEL: @calloc_constant_size(265; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @calloc(i64 16, i64 8)266; CHECK-NEXT: ret ptr [[CALL]]267;268 %call = tail call noalias ptr @calloc(i64 16, i64 8)269 ret ptr %call270}271 272define noalias ptr @calloc_constant_size_overflow() {273; CHECK-LABEL: @calloc_constant_size_overflow(274; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)275; CHECK-NEXT: ret ptr [[CALL]]276;277 %call = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)278 ret ptr %call279}280 281define noalias ptr @op_new_nonconstant_size(i64 %n) {282; CHECK-LABEL: @op_new_nonconstant_size(283; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 [[N:%.*]])284; CHECK-NEXT: ret ptr [[CALL]]285;286 %call = tail call ptr @_Znam(i64 %n)287 ret ptr %call288}289 290define noalias ptr @op_new_constant_size() {291; CHECK-LABEL: @op_new_constant_size(292; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znam(i64 40)293; CHECK-NEXT: ret ptr [[CALL]]294;295 %call = tail call ptr @_Znam(i64 40)296 ret ptr %call297}298 299define noalias ptr @op_new_constant_size2() {300; CHECK-LABEL: @op_new_constant_size2(301; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znwm(i64 40)302; CHECK-NEXT: ret ptr [[CALL]]303;304 %call = tail call ptr @_Znwm(i64 40)305 ret ptr %call306}307 308define noalias ptr @op_new_constant_zero_size() {309; CHECK-LABEL: @op_new_constant_zero_size(310; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 0)311; CHECK-NEXT: ret ptr [[CALL]]312;313 %call = tail call ptr @_Znam(i64 0)314 ret ptr %call315}316 317define noalias ptr @strdup_constant_str() {318; CHECK-LABEL: @strdup_constant_str(319; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(6) ptr @strdup(ptr nonnull @.str)320; CHECK-NEXT: ret ptr [[CALL]]321;322 %call = tail call noalias ptr @strdup(ptr @.str)323 ret ptr %call324}325 326define noalias ptr @strdup_notconstant_str(ptr %str) {327; CHECK-LABEL: @strdup_notconstant_str(328; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @strdup(ptr [[STR:%.*]])329; CHECK-NEXT: ret ptr [[CALL]]330;331 %call = tail call noalias ptr @strdup(ptr %str)332 ret ptr %call333}334 335; OSS-Fuzz #23214336; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23214337define noalias ptr @ossfuzz_23214() {338; CHECK-LABEL: @ossfuzz_23214(339; CHECK-NEXT: bb:340; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) ptr @aligned_alloc(i64 -9223372036854775808, i64 512)341; CHECK-NEXT: ret ptr [[CALL]]342;343bb:344 %and = and i64 -1, -9223372036854775808345 %call = tail call noalias ptr @aligned_alloc(i64 %and, i64 512)346 ret ptr %call347}348 349define noalias ptr @op_new_align() {350; CHECK-LABEL: @op_new_align(351; CHECK-NEXT: [[CALL:%.*]] = tail call align 32 dereferenceable_or_null(32) ptr @_ZnamSt11align_val_t(i64 32, i64 32)352; CHECK-NEXT: ret ptr [[CALL]]353;354 %call = tail call ptr @_ZnamSt11align_val_t(i64 32, i64 32)355 ret ptr %call356}357 358define ptr @my_malloc_constant_size() {359; CHECK-LABEL: @my_malloc_constant_size(360; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(32) ptr @my_malloc(i64 32)361; CHECK-NEXT: ret ptr [[CALL]]362;363 %call = call ptr @my_malloc(i64 32)364 ret ptr %call365}366 367define ptr @my_calloc_constant_size() {368; CHECK-LABEL: @my_calloc_constant_size(369; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(128) ptr @my_calloc(i64 32, i64 4)370; CHECK-NEXT: ret ptr [[CALL]]371;372 %call = call ptr @my_calloc(i64 32, i64 4)373 ret ptr %call374}375 376define ptr @virtual_constant_size(ptr %alloc) {377; CHECK-LABEL: @virtual_constant_size(378; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(16) ptr [[ALLOC:%.*]](i64 16) #[[ATTR5:[0-9]+]]379; CHECK-NEXT: ret ptr [[CALL]]380;381 %call = call ptr %alloc(i64 16) allocsize(0)382 ret ptr %call383}384