brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · b135f76 Raw
141 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare noalias ptr @calloc(i32, i32) nounwind allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"5declare void @free(ptr) allockind("free") "alloc-family"="malloc"6 7; Test load from uninitialized alloca - should be removed and replaced with undef8define i32 @test_load_uninitialized_alloca() {9; CHECK-LABEL: @test_load_uninitialized_alloca(10; CHECK-NEXT:    ret i32 undef11;12  %a = alloca i3213  %v = load i32, ptr %a14  ret i32 %v15}16 17; Test load from zero-initialized malloc - should be removed and replaced with zero18define i32 @test_load_zero_initialized_malloc() {19; CHECK-LABEL: @test_load_zero_initialized_malloc(20; CHECK-NEXT:    ret i32 021;22  %a = call ptr @calloc(i32 1, i32 4)23  %v = load i32, ptr %a24  call void @free(ptr %a)25  ret i32 %v26}27 28; Test memcpy from uninitialized source - should be removed29define void @test_memcpy_from_uninitialized_alloca(ptr %dest) {30; CHECK-LABEL: @test_memcpy_from_uninitialized_alloca(31; CHECK-NEXT:    ret void32;33  %src = alloca i32, align 134  call void @llvm.memcpy.p0.p0.i32(ptr %src, ptr %src, i32 4, i1 false)35  call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 4, i1 false)36  ret void37}38 39; Test memcpy from zeroed source - should transform to memset with zero40define void @test_memcpy_from_uninitialized_calloc(ptr %dest) {41; CHECK-LABEL: @test_memcpy_from_uninitialized_calloc(42; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(16) [[DEST:%.*]], i8 0, i32 16, i1 false)43; CHECK-NEXT:    ret void44;45  %src = call ptr @calloc(i32 1, i32 16)46  call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 16, i1 false)47  call void @free(ptr %src)48  ret void49}50 51; Test mixed read/write pattern - should not be removable due to write before read52define i32 @test_write_then_read_alloca() {53; CHECK-LABEL: @test_write_then_read_alloca(54; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 455; CHECK-NEXT:    store i8 42, ptr [[A]], align 156; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[A]], align 457; CHECK-NEXT:    ret i32 [[V]]58;59  %a = alloca i3260  store i8 42, ptr %a61  %v = load i32, ptr %a62  ret i32 %v63}64 65; Test read then write pattern - should not be removable due to conflicting access66define void @test_read_then_write_alloca() {67; CHECK-LABEL: @test_read_then_write_alloca(68; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 469; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[A]], align 470; CHECK-NEXT:    [[V8:%.*]] = trunc i32 [[V]] to i871; CHECK-NEXT:    store i8 [[V8]], ptr [[A]], align 172; CHECK-NEXT:    ret void73;74  %a = alloca i3275  %v = load i32, ptr %a76  %v8 = trunc i32 %v to i877  store i8 %v8, ptr %a78  ret void79}80 81; Test load through GEP from uninitialized alloca82define i8 @test_load_gep_uninitialized_alloca() {83; CHECK-LABEL: @test_load_gep_uninitialized_alloca(84; CHECK-NEXT:    ret i8 undef85;86  %a = alloca [4 x i8]87  %gep = getelementptr [4 x i8], ptr %a, i32 0, i32 288  %v = load i8, ptr %gep89  ret i8 %v90}91 92; Test load through bitcast from uninitialized alloca93define i16 @test_load_bitcast_uninitialized_alloca() {94; CHECK-LABEL: @test_load_bitcast_uninitialized_alloca(95; CHECK-NEXT:    ret i16 undef96;97  %a = alloca i3298  %bc = bitcast ptr %a to ptr99  %v = load i16, ptr %bc100  ret i16 %v101}102 103; Test memmove from zero-initialized malloc104define void @test_memmove_from_zero_initialized_malloc(ptr %dest) {105; CHECK-LABEL: @test_memmove_from_zero_initialized_malloc(106; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(32) [[DEST:%.*]], i8 0, i32 32, i1 false)107; CHECK-NEXT:    ret void108;109  %src = call ptr @calloc(i32 8, i32 4)110  call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %src, i32 32, i1 false)111  call void @free(ptr %src)112  ret void113}114 115; Test multiple loads from same uninitialized alloca116define { i32, i32 } @test_multiple_loads_uninitialized_alloca() {117; CHECK-LABEL: @test_multiple_loads_uninitialized_alloca(118; CHECK-NEXT:    ret { i32, i32 } undef119;120  %a = alloca [2 x i32]121  %gep1 = getelementptr [2 x i32], ptr %a, i32 0, i32 0122  %gep2 = getelementptr [2 x i32], ptr %a, i32 0, i32 1123  %v1 = load i32, ptr %gep1124  %v2 = load i32, ptr %gep2125  %ret = insertvalue { i32, i32 } { i32 undef, i32 poison }, i32 %v1, 0126  %ret2 = insertvalue { i32, i32 } %ret, i32 %v2, 1127  ret { i32, i32 } %ret2128}129 130; Test that volatile operations prevent removal131define i32 @test_volatile_load_prevents_removal() {132; CHECK-LABEL: @test_volatile_load_prevents_removal(133; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4134; CHECK-NEXT:    [[V:%.*]] = load volatile i32, ptr [[A]], align 4135; CHECK-NEXT:    ret i32 [[V]]136;137  %a = alloca i32138  %v = load volatile i32, ptr %a139  ret i32 %v140}141