brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · e719e6d Raw
341 lines · plain
1; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s2 3declare dso_local void @val_fn(<vscale x 4 x float>)4declare dso_local void @ptr_fn(ptr)5 6; An alloca of a scalable vector shouldn't trigger stack protection.7 8; CHECK-LABEL: call_value:9; CHECK-NOT: mov x19, sp10; CHECK: addvl sp, sp, #-111; CHECK-NOT: __stack_chk_guard12; CHECK: str {{z[0-9]+}}, [x29, #-1, mul vl]13define void @call_value() #0 {14entry:15  %x = alloca <vscale x 4 x float>, align 1616  store <vscale x 4 x float> zeroinitializer, ptr %x, align 1617  %0 = load <vscale x 4 x float>, ptr %x, align 1618  call void @val_fn(<vscale x 4 x float> %0)19  ret void20}21 22; CHECK-LABEL: call_value_strong:23; CHECK-NOT: mov x19, sp24; CHECK: addvl sp, sp, #-125; CHECK-NOT: __stack_chk_guard26; CHECK: str {{z[0-9]+}}, [x29, #-1, mul vl]27define void @call_value_strong() #1 {28entry:29  %x = alloca <vscale x 4 x float>, align 1630  store <vscale x 4 x float> zeroinitializer, ptr %x, align 1631  %0 = load <vscale x 4 x float>, ptr %x, align 1632  call void @val_fn(<vscale x 4 x float> %0)33  ret void34}35 36; Address-taking of a scalable vector should trigger stack protection only with37; sspstrong, and the scalable vector should be be placed below the stack guard.38 39; CHECK-LABEL: call_ptr:40; CHECK-NOT: mov x19, sp41; CHECK: addvl sp, sp, #-142; CHECK-NOT: __stack_chk_guard43; CHECK: addvl x0, x29, #-144; CHECK: bl ptr_fn45define void @call_ptr() #0 {46entry:47  %x = alloca <vscale x 4 x float>, align 1648  call void @ptr_fn(ptr %x)49  ret void50}51 52; CHECK-LABEL: call_ptr_strong:53; CHECK: mov x29, sp54; CHECK: addvl sp, sp, #-255; CHECK-DAG: addvl [[ADDR:x[0-9]+]], x29, #-156; CHECK-DAG: ldr [[VAL:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard]57; CHECK-DAG: str [[VAL]], [[[ADDR]]]58; CHECK-DAG: addvl x0, x29, #-259; CHECK: bl ptr_fn60define void @call_ptr_strong() #1 {61entry:62  %x = alloca <vscale x 4 x float>, align 1663  call void @ptr_fn(ptr %x)64  ret void65}66 67; Check that both variables are addressed in the same way68 69; CHECK-LABEL: call_both:70; CHECK: mov x29, sp71; CHECK: addvl sp, sp, #-272; CHECK-NOT: __stack_chk_guard73; CHECK: str {{z[0-9]+}}, [x29, #-1, mul vl]74; CHECK: bl val_fn75; CHECK: addvl x0, x29, #-276; CHECK: bl ptr_fn77define void @call_both() #0 {78entry:79  %x = alloca <vscale x 4 x float>, align 1680  %y = alloca <vscale x 4 x float>, align 1681  store <vscale x 4 x float> zeroinitializer, ptr %x, align 1682  %0 = load <vscale x 4 x float>, ptr %x, align 1683  call void @val_fn(<vscale x 4 x float> %0)84  call void @ptr_fn(ptr %y)85  ret void86}87 88; CHECK-LABEL: call_both_strong:89; CHECK: mov x29, sp90; CHECK: addvl sp, sp, #-391; CHECK-DAG: addvl [[ADDR:x[0-9]+]], x29, #-192; CHECK-DAG: ldr [[VAL:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard]93; CHECK-DAG: str [[VAL]], [[[ADDR]]]94; CHECK-DAG: str {{z[0-9]+}}, [x29, #-2, mul vl]95; CHECK: bl val_fn96; CHECK: addvl x0, x29, #-397; CHECK: bl ptr_fn98define void @call_both_strong() #1 {99entry:100  %x = alloca <vscale x 4 x float>, align 16101  %y = alloca <vscale x 4 x float>, align 16102  store <vscale x 4 x float> zeroinitializer, ptr %x, align 16103  %0 = load <vscale x 4 x float>, ptr %x, align 16104  call void @val_fn(<vscale x 4 x float> %0)105  call void @ptr_fn(ptr %y)106  ret void107}108 109; Pushed callee-saved regs should be above the stack guard110 111; CHECK-LABEL: callee_save:112; CHECK: mov x29, sp113; CHECK: addvl sp, sp, #-18114; CHECK: str {{z[0-9]+}}, [sp, #{{[0-9]+}}, mul vl]115; CHECK-NOT: mov x29, sp116; CHECK: addvl sp, sp, #-1117; CHECK-NOT: __stack_chk_guard118; CHECK: str {{z[0-9]+}}, [x29, #-19, mul vl]119define void @callee_save(<vscale x 4 x float> %x) #0 {120entry:121  %x.addr = alloca <vscale x 4 x float>, align 16122  store <vscale x 4 x float> %x, ptr %x.addr, align 16123  call void @ptr_fn(ptr %x.addr)124  ret void125}126 127; CHECK-LABEL: callee_save_strong:128; CHECK: mov x29, sp129; CHECK: addvl sp, sp, #-18130; CHECK: str {{z[0-9]+}}, [sp, #{{[0-9]+}}, mul vl]131; CHECK: addvl sp, sp, #-2132; CHECK-DAG: addvl [[ADDR:x[0-9]+]], x29, #-19133; CHECK-DAG: ldr [[VAL:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard]134; CHECK-DAG: str [[VAL]], [[[ADDR]]]135; CHECK-DAG: str z0, [x29, #-20, mul vl]136define void @callee_save_strong(<vscale x 4 x float> %x) #1 {137entry:138  %x.addr = alloca <vscale x 4 x float>, align 16139  store <vscale x 4 x float> %x, ptr %x.addr, align 16140  call void @ptr_fn(ptr %x.addr)141  ret void142}143 144; Check that local stack allocation works correctly both when we have a stack145; guard but no vulnerable SVE objects, and when we do have such objects.146 147; CHECK-LABEL: local_stack_alloc:148; CHECK: mov x29, sp149; CHECK: sub sp, sp, #16, lsl #12150; CHECK: sub sp, sp, #16151; CHECK: addvl sp, sp, #-2152 153; Stack guard is placed below the SVE stack area (and above all fixed-width objects)154; CHECK-DAG: add [[STACK_GUARD_SPILL_PART_LOC:x[0-9]+]], sp, #8, lsl #12155; CHECK-DAG: add [[STACK_GUARD_SPILL_PART_LOC]], [[STACK_GUARD_SPILL_PART_LOC]], #16156; CHECK-DAG: ldr [[STACK_GUARD:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard]157; CHECK-DAG: str [[STACK_GUARD]], [[[STACK_GUARD_SPILL_PART_LOC]], #32760]158 159; char_arr is below the stack guard160; CHECK-DAG: add [[CHAR_ARR_LOC:x[0-9]+]], sp, #16, lsl #12161; CHECK-DAG: strb wzr, [[[CHAR_ARR_LOC]]]162 163; large1 is accessed via a virtual base register164; CHECK-DAG: add [[LARGE1:x[0-9]+]], sp, #8, lsl #12165; CHECK-DAG: stp x0, x0, [[[LARGE1]]]166 167; large2 is at the bottom of the stack168; CHECK-DAG: stp x0, x0, [sp]169 170; vec1 and vec2 are in the SVE stack immediately below fp171; CHECK-DAG: addvl x0, x29, #-1172; CHECK-DAG: bl ptr_fn173; CHECK-DAG: addvl x0, x29, #-2174; CHECK-DAG: bl ptr_fn175define void @local_stack_alloc(i64 %val) #0 {176entry:177  %char_arr = alloca [8 x i8], align 4178  %gep0 = getelementptr [8 x i8], ptr %char_arr, i64 0, i64 0179  store i8 0, ptr %gep0, align 8180  %large1 = alloca [4096 x i64], align 8181  %large2 = alloca [4096 x i64], align 8182  %vec_1 = alloca <vscale x 4 x float>, align 16183  %vec_2 = alloca <vscale x 4 x float>, align 16184  %gep1 = getelementptr [4096 x i64], ptr %large1, i64 0, i64 0185  %gep2 = getelementptr [4096 x i64], ptr %large1, i64 0, i64 1186  store i64 %val, ptr %gep1, align 8187  store i64 %val, ptr %gep2, align 8188  %gep3 = getelementptr [4096 x i64], ptr %large2, i64 0, i64 0189  %gep4 = getelementptr [4096 x i64], ptr %large2, i64 0, i64 1190  store i64 %val, ptr %gep3, align 8191  store i64 %val, ptr %gep4, align 8192  call void @ptr_fn(ptr %vec_1)193  call void @ptr_fn(ptr %vec_2)194  ret void195}196 197; CHECK-LABEL: local_stack_alloc_strong:198; CHECK: mov x29, sp199; CHECK: sub sp, sp, #16, lsl #12200; CHECK: sub sp, sp, #16201; CHECK: addvl sp, sp, #-3202 203; Stack guard is placed at the top of the SVE stack area204; CHECK-DAG: ldr [[STACK_GUARD:x[0-9]+]], [{{x[0-9]+}}, :lo12:__stack_chk_guard]205; CHECK-DAG: addvl [[STACK_GUARD_POS:x[0-9]+]], x29, #-1206; CHECK-DAG: str [[STACK_GUARD]], [[[STACK_GUARD_POS]]]207 208; char_arr is below the SVE stack area209; CHECK-DAG: add [[CHAR_ARR:x[0-9]+]], sp, #15, lsl #12            // =61440210; CHECK-DAG: add [[CHAR_ARR]], [[CHAR_ARR]], #9211; CHECK-DAG: strb wzr, [[[CHAR_ARR]], #4095]212 213; large1 is accessed via a virtual base register214; CHECK-DAG: add [[LARGE1:x[0-9]+]], sp, #8, lsl #12215; CHECK-DAG: stp x0, x0, [[[LARGE1]], #8]216 217; large2 is at the bottom of the stack218; CHECK-DAG: stp x0, x0, [sp, #8]219 220; vec1 and vec2 are in the SVE stack area below the stack guard221; CHECK-DAG: addvl x0, x29, #-2222; CHECK-DAG: bl ptr_fn223; CHECK-DAG: addvl x0, x29, #-3224; CHECK-DAG: bl ptr_fn225define void @local_stack_alloc_strong(i64 %val) #1 {226entry:227  %char_arr = alloca [8 x i8], align 4228  %gep0 = getelementptr [8 x i8], ptr %char_arr, i64 0, i64 0229  store i8 0, ptr %gep0, align 8230  %large1 = alloca [4096 x i64], align 8231  %large2 = alloca [4096 x i64], align 8232  %vec_1 = alloca <vscale x 4 x float>, align 16233  %vec_2 = alloca <vscale x 4 x float>, align 16234  %gep1 = getelementptr [4096 x i64], ptr %large1, i64 0, i64 0235  %gep2 = getelementptr [4096 x i64], ptr %large1, i64 0, i64 1236  store i64 %val, ptr %gep1, align 8237  store i64 %val, ptr %gep2, align 8238  %gep3 = getelementptr [4096 x i64], ptr %large2, i64 0, i64 0239  %gep4 = getelementptr [4096 x i64], ptr %large2, i64 0, i64 1240  store i64 %val, ptr %gep3, align 8241  store i64 %val, ptr %gep4, align 8242  call void @ptr_fn(ptr %vec_1)243  call void @ptr_fn(ptr %vec_2)244  ret void245}246 247; A GEP addressing into a vector of <vscale x 4 x float> is in-bounds for248; offsets up to 3, but out-of-bounds (and so triggers stack protection with249; sspstrong) after that.250 251; CHECK-LABEL: vector_gep_3:252; CHECK-NOT: __stack_chk_guard253define void @vector_gep_3() #0 {254entry:255  %vec = alloca <vscale x 4 x float>, align 16256  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 3257  store float 0.0, ptr %gep, align 4258  ret void259}260 261; CHECK-LABEL: vector_gep_4:262; CHECK-NOT: __stack_chk_guard263define void @vector_gep_4() #0 {264entry:265  %vec = alloca <vscale x 4 x float>, align 16266  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 4267  store float 0.0, ptr %gep, align 4268  ret void269}270 271; CHECK-LABEL: vector_gep_twice:272; CHECK-NOT: __stack_chk_guard273define void @vector_gep_twice() #0 {274entry:275  %vec = alloca <vscale x 4 x float>, align 16276  %gep1 = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 3277  store float 0.0, ptr %gep1, align 4278  %gep2 = getelementptr float, ptr %gep1, i64 1279  store float 0.0, ptr %gep2, align 4280  ret void281}282 283; CHECK-LABEL: vector_gep_n:284; CHECK-NOT: __stack_chk_guard285define void @vector_gep_n(i64 %n) #0 {286entry:287  %vec = alloca <vscale x 4 x float>, align 16288  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 %n289  store float 0.0, ptr %gep, align 4290  ret void291}292 293; CHECK-LABEL: vector_gep_3_strong:294; CHECK-NOT: __stack_chk_guard295define void @vector_gep_3_strong() #1 {296entry:297  %vec = alloca <vscale x 4 x float>, align 16298  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 3299  store float 0.0, ptr %gep, align 4300  ret void301}302 303; CHECK-LABEL: vector_gep_4_strong:304; CHECK: __stack_chk_guard305define void @vector_gep_4_strong(i64 %val) #1 {306entry:307  %vec = alloca <vscale x 4 x float>, align 16308  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 4309  store float 0.0, ptr %gep, align 4310  ret void311}312 313 314; CHECK-LABEL: vector_gep_twice_strong:315; CHECK: __stack_chk_guard316define void @vector_gep_twice_strong() #1 {317entry:318  %vec = alloca <vscale x 4 x float>, align 16319  %gep1 = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 3320  store float 0.0, ptr %gep1, align 4321  %gep2 = getelementptr float, ptr %gep1, i64 1322  store float 0.0, ptr %gep2, align 4323  ret void324}325 326; CHECK-LABEL: vector_gep_n_strong:327; CHECK: __stack_chk_guard328define void @vector_gep_n_strong(i64 %n) #1 {329entry:330  %vec = alloca <vscale x 4 x float>, align 16331  %gep = getelementptr <vscale x 4 x float>, ptr %vec, i64 0, i64 %n332  store float 0.0, ptr %gep, align 4333  ret void334}335 336attributes #0 = { ssp "frame-pointer"="non-leaf" }337attributes #1 = { sspstrong "frame-pointer"="non-leaf" }338 339!llvm.module.flags = !{!0}340!0 = !{i32 7, !"direct-access-external-data", i32 1}341