brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 3b77e49 Raw
177 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG4target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-f80:128-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"5 6declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind7declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1) nounwind8declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind9 10; This tests that allocas are not split into slices that are not byte width multiple11;.12; CHECK: @foo_copy_source = external constant %union.Foo13; CHECK: @i64_sink = global i64 014;.15define void @no_split_on_non_byte_width(i32) {16; CHECK-LABEL: @no_split_on_non_byte_width(17; CHECK-NEXT:    [[ARG_SROA_0:%.*]] = alloca i8, align 818; CHECK-NEXT:    [[ARG_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[TMP0:%.*]] to i819; CHECK-NEXT:    store i8 [[ARG_SROA_0_0_EXTRACT_TRUNC]], ptr [[ARG_SROA_0]], align 820; CHECK-NEXT:    [[ARG_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[TMP0]], 821; CHECK-NEXT:    [[ARG_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[ARG_SROA_3_0_EXTRACT_SHIFT]] to i2422; CHECK-NEXT:    br label [[LOAD_I32:%.*]]23; CHECK:       load_i32:24; CHECK-NEXT:    [[ARG_SROA_0_0_ARG_SROA_0_0_R01:%.*]] = load i8, ptr [[ARG_SROA_0]], align 825; CHECK-NEXT:    br label [[LOAD_I1:%.*]]26; CHECK:       load_i1:27; CHECK-NEXT:    [[ARG_SROA_0_0_ARG_SROA_0_0_T1:%.*]] = load i1, ptr [[ARG_SROA_0]], align 828; CHECK-NEXT:    ret void29;30  %arg = alloca i32 , align 831  store i32 %0, ptr %arg32  br label %load_i3233 34load_i32:35  %r0 = load i32, ptr %arg36  br label %load_i137 38load_i1:39  %t1 = load i1, ptr %arg40  ret void41}42 43; PR18726: Check that we use memcpy and memset to fill out padding when we have44; a slice with a simple single type whose store size is smaller than the slice45; size.46 47%union.Foo = type { x86_fp80, i64, i64 }48 49@foo_copy_source = external constant %union.Foo50@i64_sink = global i64 051 52define void @memcpy_fp80_padding() {53; CHECK-LABEL: @memcpy_fp80_padding(54; CHECK-NEXT:    [[X_SROA_0:%.*]] = alloca x86_fp80, align 1655; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[X_SROA_0]], ptr align 16 @foo_copy_source, i32 16, i1 false)56; CHECK-NEXT:    [[X_SROA_1_0_COPYLOAD:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @foo_copy_source, i64 16), align 1657; CHECK-NEXT:    [[X_SROA_2_0_COPYLOAD:%.*]] = load i64, ptr getelementptr inbounds (i8, ptr @foo_copy_source, i64 24), align 858; CHECK-NEXT:    store i64 [[X_SROA_1_0_COPYLOAD]], ptr @i64_sink, align 459; CHECK-NEXT:    ret void60;61  %x = alloca %union.Foo62 63  ; Copy from a global.64  call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 16 @foo_copy_source, i32 32, i1 false)65 66  ; Access a slice of the alloca to trigger SROA.67  %mid_p = getelementptr %union.Foo, ptr %x, i32 0, i32 168  %elt = load i64, ptr %mid_p69  store i64 %elt, ptr @i64_sink70  ret void71}72 73define void @memset_fp80_padding() {74; CHECK-LABEL: @memset_fp80_padding(75; CHECK-NEXT:    [[X_SROA_0:%.*]] = alloca x86_fp80, align 1676; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr align 16 [[X_SROA_0]], i8 -1, i32 16, i1 false)77; CHECK-NEXT:    store i64 -1, ptr @i64_sink, align 478; CHECK-NEXT:    ret void79;80  %x = alloca %union.Foo81 82  ; Set to all ones.83  call void @llvm.memset.p0.i32(ptr align 16 %x, i8 -1, i32 32, i1 false)84 85  ; Access a slice of the alloca to trigger SROA.86  %mid_p = getelementptr %union.Foo, ptr %x, i32 0, i32 187  %elt = load i64, ptr %mid_p88  store i64 %elt, ptr @i64_sink89  ret void90}91 92%S.vec3float = type { float, float, float }93%U.vec3float = type { <4 x float> }94 95declare i32 @memcpy_vec3float_helper(ptr)96 97; PR18726: Check that SROA does not rewrite a 12-byte memcpy into a 16-byte98; vector store, hence accidentally putting gibberish onto the stack.99define i32 @memcpy_vec3float_widening(ptr %x) !prof !0 {100; CHECK-LABEL: @memcpy_vec3float_widening(101; CHECK-NEXT:  entry:102; CHECK-NEXT:    [[TMP1_SROA_0_0_COPYLOAD:%.*]] = load <3 x float>, ptr [[X:%.*]], align 4103; CHECK-NEXT:    [[TMP1_SROA_0_0_VEC_EXPAND:%.*]] = shufflevector <3 x float> [[TMP1_SROA_0_0_COPYLOAD]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>104; CHECK-NEXT:    [[TMP1_SROA_0_0_VECBLEND:%.*]] = select <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x float> [[TMP1_SROA_0_0_VEC_EXPAND]], <4 x float> undef, !prof [[PROF1:![0-9]+]]105; CHECK-NEXT:    [[TMP2:%.*]] = alloca [[S_VEC3FLOAT:%.*]], align 4106; CHECK-NEXT:    [[TMP1_SROA_0_0_VEC_EXTRACT:%.*]] = shufflevector <4 x float> [[TMP1_SROA_0_0_VECBLEND]], <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>107; CHECK-NEXT:    store <3 x float> [[TMP1_SROA_0_0_VEC_EXTRACT]], ptr [[TMP2]], align 4108; CHECK-NEXT:    [[RESULT:%.*]] = call i32 @memcpy_vec3float_helper(ptr [[TMP2]])109; CHECK-NEXT:    ret i32 [[RESULT]]110;111entry:112  ; Create a temporary variable %tmp1 and copy %x[0] into it113  %tmp1 = alloca %S.vec3float, align 4114  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %tmp1, ptr align 4 %x, i32 12, i1 false)115 116  ; The following block does nothing; but appears to confuse SROA117  %unused3 = load <4 x float>, ptr %tmp1, align 1118 119  ; Create a second temporary and copy %tmp1 into it120  %tmp2 = alloca %S.vec3float, align 4121  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %tmp2, ptr align 4 %tmp1, i32 12, i1 false)122 123  %result = call i32 @memcpy_vec3float_helper(ptr %tmp2)124  ret i32 %result125}126 127; Don't crash on length that is constant expression.128 129define void @PR50888() {130; CHECK-LABEL: @PR50888(131; CHECK-NEXT:    [[ARRAY:%.*]] = alloca i8, align 1132; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[ARRAY]], i8 0, i64 ptrtoint (ptr @PR50888 to i64), i1 false)133; CHECK-NEXT:    ret void134;135  %array = alloca i8136  call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 ptrtoint (ptr @PR50888 to i64), i1 false)137  ret void138}139 140; Don't crash on out-of-bounds length.141 142define void @PR50910() {143; CHECK-LABEL: @PR50910(144; CHECK-NEXT:    [[T1:%.*]] = alloca i8, i64 1, align 8145; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[T1]], i8 0, i64 1, i1 false)146; CHECK-NEXT:    ret void147;148  %t1 = alloca i8, i64 1, align 8149  call void @llvm.memset.p0.i64(ptr align 8 %t1, i8 0, i64 4294967296, i1 false)150  ret void151}152 153define i1 @presplit_overlarge_load() {154; CHECK-LABEL: @presplit_overlarge_load(155; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i8, align 2156; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_L11:%.*]] = load i8, ptr [[A_SROA_0]], align 2157; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_L2:%.*]] = load i1, ptr [[A_SROA_0]], align 2158; CHECK-NEXT:    ret i1 [[A_SROA_0_0_A_SROA_0_0_L2]]159;160  %A = alloca i16161  %L1 = load i32, ptr %A162  %L2 = load i1, ptr %A163  ret i1 %L2164}165!0 = !{!"function_entry_count", i32 10}166 167;.168; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }169; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }170;.171; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}172; CHECK: [[PROF1]] = !{!"unknown", !"sroa"}173;.174;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:175; CHECK-MODIFY-CFG: {{.*}}176; CHECK-PRESERVE-CFG: {{.*}}177