brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · bd69981 Raw
234 lines · plain
1; RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=stack-protector \2; RUN:   -stop-after=stack-protector -o - < %s | FileCheck %s3; Bugs 42238/43308: Test some additional situations not caught previously.4 5define void @store_captures() #0 {6; CHECK-LABEL: @store_captures(7; CHECK-NEXT:  entry:8; CHECK-NEXT:    [[STACKGUARDSLOT:%.*]] = alloca ptr9; CHECK-NEXT:    [[STACKGUARD:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))10; CHECK-NEXT:    call void @llvm.stackprotector(ptr [[STACKGUARD]], ptr [[STACKGUARDSLOT]])11; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 412; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 413; CHECK-NEXT:    [[J:%.*]] = alloca ptr, align 814; CHECK-NEXT:    store i32 0, ptr [[RETVAL]]15; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[A]], align 416; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LOAD]], 117; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 418; CHECK-NEXT:    store ptr [[A]], ptr [[J]], align 819; CHECK-NEXT:    [[STACKGUARD1:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))20; CHECK-NEXT:    [[TMP0:%.*]] = load volatile ptr, ptr [[STACKGUARDSLOT]]21; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[STACKGUARD1]], [[TMP0]]22; CHECK-NEXT:    br i1 [[TMP1]], label [[SP_RETURN:%.*]], label [[CALLSTACKCHECKFAILBLK:%.*]], !prof !023; CHECK:       SP_return:24; CHECK-NEXT:    ret void25; CHECK:       CallStackCheckFailBlk:26; CHECK-NEXT:    call void @__stack_chk_fail()27; CHECK-NEXT:    unreachable28;29entry:30  %retval = alloca i32, align 431  %a = alloca i32, align 432  %j = alloca ptr, align 833  store i32 0, ptr %retval34  %load = load i32, ptr %a, align 435  %add = add nsw i32 %load, 136  store i32 %add, ptr %a, align 437  store ptr %a, ptr %j, align 838  ret void39}40 41define ptr @non_captures() #0 {42; load, atomicrmw, and ret do not trigger a stack protector.43; CHECK-LABEL: @non_captures(44; CHECK-NEXT:  entry:45; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 446; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[A]], align 447; CHECK-NEXT:    [[ATOM:%.*]] = atomicrmw add ptr [[A]], i32 1 seq_cst48; CHECK-NEXT:    ret ptr [[A]]49;50entry:51  %a = alloca i32, align 452  %load = load i32, ptr %a, align 453  %atom = atomicrmw add ptr %a, i32 1 seq_cst54  ret ptr %a55}56 57define void @store_addrspacecast_captures() #0 {58; CHECK-LABEL: @store_addrspacecast_captures(59; CHECK-NEXT:  entry:60; CHECK-NEXT:    [[STACKGUARDSLOT:%.*]] = alloca ptr61; CHECK-NEXT:    [[STACKGUARD:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))62; CHECK-NEXT:    call void @llvm.stackprotector(ptr [[STACKGUARD]], ptr [[STACKGUARDSLOT]])63; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 464; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 465; CHECK-NEXT:    [[J:%.*]] = alloca ptr addrspace(1), align 866; CHECK-NEXT:    store i32 0, ptr [[RETVAL]]67; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[A]], align 468; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LOAD]], 169; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 470; CHECK-NEXT:    [[A_ADDRSPACECAST:%.*]] = addrspacecast ptr [[A]] to ptr addrspace(1)71; CHECK-NEXT:    store ptr addrspace(1) [[A_ADDRSPACECAST]], ptr [[J]], align 872; CHECK-NEXT:    [[STACKGUARD1:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))73; CHECK-NEXT:    [[TMP0:%.*]] = load volatile ptr, ptr [[STACKGUARDSLOT]]74; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[STACKGUARD1]], [[TMP0]]75; CHECK-NEXT:    br i1 [[TMP1]], label [[SP_RETURN:%.*]], label [[CALLSTACKCHECKFAILBLK:%.*]], !prof !076; CHECK:       SP_return:77; CHECK-NEXT:    ret void78; CHECK:       CallStackCheckFailBlk:79; CHECK-NEXT:    call void @__stack_chk_fail()80; CHECK-NEXT:    unreachable81;82entry:83  %retval = alloca i32, align 484  %a = alloca i32, align 485  %j = alloca ptr addrspace(1), align 886  store i32 0, ptr %retval87  %load = load i32, ptr %a, align 488  %add = add nsw i32 %load, 189  store i32 %add, ptr %a, align 490  %a.addrspacecast = addrspacecast ptr %a to ptr addrspace(1)91  store ptr addrspace(1) %a.addrspacecast, ptr %j, align 892  ret void93}94 95define void @cmpxchg_captures() #0 {96; CHECK-LABEL: @cmpxchg_captures(97; CHECK-NEXT:  entry:98; CHECK-NEXT:    [[STACKGUARDSLOT:%.*]] = alloca ptr99; CHECK-NEXT:    [[STACKGUARD:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))100; CHECK-NEXT:    call void @llvm.stackprotector(ptr [[STACKGUARD]], ptr [[STACKGUARDSLOT]])101; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4102; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4103; CHECK-NEXT:    [[J:%.*]] = alloca ptr, align 8104; CHECK-NEXT:    store i32 0, ptr [[RETVAL]]105; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[A]], align 4106; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LOAD]], 1107; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 4108; CHECK-NEXT:    [[TMP0:%.*]] = cmpxchg ptr [[J]], ptr null, ptr [[A]] seq_cst monotonic109; CHECK-NEXT:    [[STACKGUARD1:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))110; CHECK-NEXT:    [[TMP1:%.*]] = load volatile ptr, ptr [[STACKGUARDSLOT]]111; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[STACKGUARD1]], [[TMP1]]112; CHECK-NEXT:    br i1 [[TMP2]], label [[SP_RETURN:%.*]], label [[CALLSTACKCHECKFAILBLK:%.*]], !prof !0113; CHECK:       SP_return:114; CHECK-NEXT:    ret void115; CHECK:       CallStackCheckFailBlk:116; CHECK-NEXT:    call void @__stack_chk_fail()117; CHECK-NEXT:    unreachable118;119entry:120  %retval = alloca i32, align 4121  %a = alloca i32, align 4122  %j = alloca ptr, align 8123  store i32 0, ptr %retval124  %load = load i32, ptr %a, align 4125  %add = add nsw i32 %load, 1126  store i32 %add, ptr %a, align 4127 128  cmpxchg ptr %j, ptr null, ptr %a seq_cst monotonic129  ret void130}131 132define void @memset_captures(i64 %c) #0 {133; CHECK-LABEL: @memset_captures(134; CHECK-NEXT:  entry:135; CHECK-NEXT:    [[STACKGUARDSLOT:%.*]] = alloca ptr136; CHECK-NEXT:    [[STACKGUARD:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))137; CHECK-NEXT:    call void @llvm.stackprotector(ptr [[STACKGUARD]], ptr [[STACKGUARDSLOT]])138; CHECK-NEXT:    [[CADDR:%.*]] = alloca i64, align 8139; CHECK-NEXT:    store i64 %c, ptr [[CADDR]], align 8140; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4141; CHECK-NEXT:    [[COUNT:%.*]] = load i64, ptr [[CADDR]], align 8142; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[I]], i8 0, i64 [[COUNT]], i1 false)143; CHECK-NEXT:    [[STACKGUARD1:%.*]] = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257))144; CHECK-NEXT:    [[TMP1:%.*]] = load volatile ptr, ptr [[STACKGUARDSLOT]]145; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[STACKGUARD1]], [[TMP1]]146; CHECK-NEXT:    br i1 [[TMP2]], label [[SP_RETURN:%.*]], label [[CALLSTACKCHECKFAILBLK:%.*]], !prof !0147; CHECK:       SP_return:148; CHECK-NEXT:    ret void149; CHECK:       CallStackCheckFailBlk:150; CHECK-NEXT:    call void @__stack_chk_fail()151; CHECK-NEXT:    unreachable152;153entry:154  %c.addr = alloca i64, align 8155  store i64 %c, ptr %c.addr, align 8156  %i = alloca i32, align 4157  %count = load i64, ptr %c.addr, align 8158  call void @llvm.memset.p0.i64(ptr align 4 %i, i8 0, i64 %count, i1 false)159  ret void160}161 162declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)163 164; Intentionally does not have any fn attrs.165declare dso_local void @foo(ptr)166 167; @bar_sspstrong and @bar_nossp are the same function, but differ only in168; function attributes. Test that a callee without stack protector function169; attribute does not trigger a stack guard slot in a caller that also does not170; have a stack protector slot.171define dso_local void @bar_sspstrong(i64 %0) #0 {172; CHECK-LABEL: @bar_sspstrong173; CHECK-NEXT: %StackGuardSlot = alloca ptr174  %2 = alloca i64, align 8175  store i64 %0, ptr %2, align 8176  %3 = load i64, ptr %2, align 8177  %4 = alloca i8, i64 %3, align 16178  call void @foo(ptr %4)179  ret void180}181 182; Intentionally does not have any fn attrs.183define dso_local void @bar_nossp(i64 %0) {184; CHECK-LABEL: @bar_nossp185; CHECK-NEXT: %2 = alloca i64186  %2 = alloca i64, align 8187  store i64 %0, ptr %2, align 8188  %3 = load i64, ptr %2, align 8189  %4 = alloca i8, i64 %3, align 16190  call void @foo(ptr %4)191  ret void192}193 194; Check stack protect for noreturn call195define dso_local i32 @foo_no_return(i32 %0) #1 {196; CHECK-LABEL: @foo_no_return197entry:198  %cmp = icmp sgt i32 %0, 4199  br i1 %cmp, label %if.then, label %if.end200 201; CHECK:      if.then:                                          ; preds = %entry202; CHECK-NEXT:   %StackGuard1 = load volatile ptr, ptr addrspace(257) inttoptr (i32 40 to ptr addrspace(257)), align 8203; CHECK-NEXT:   %1 = load volatile ptr, ptr %StackGuardSlot, align 8204; CHECK-NEXT:   %2 = icmp eq ptr %StackGuard1, %1205; CHECK-NEXT:   br i1 %2, label %SP_return, label %CallStackCheckFailBlk206; CHECK:      SP_return:                                        ; preds = %if.then207; CHECK-NEXT:   %call = call i32 @foo_no_return(i32 1)208; CHECK-NEXT:   br label %return209; CHECK:      if.end:                                           ; preds = %entry210; CHECK-NEXT:   br label %return211 212if.then:                                          ; preds = %entry213  %call = call i32 @foo_no_return(i32 1)214  br label %return215 216if.end:                                           ; preds = %entry217  br label %return218 219return:                                           ; preds = %if.end, %if.then220  ret i32 0221}222 223declare void @callee() noreturn nounwind224define void @caller() sspstrong {225; Test that a stack protector is NOT inserted when we call nounwind functions.226; CHECK-LABEL: @caller227; CHECK-NEXT: call void @callee228  call void @callee() noreturn nounwind229  ret void230}231 232attributes #0 = { sspstrong }233attributes #1 = { noreturn sspreq}234