
Despite the name, the HasAddressTaken() heuristic identifies not only allocas that have their address taken, but also those that have accesses that cannot be proven to be in-bounds. However, the current handling for phi nodes is incorrect. Phi nodes are only visited once, and will perform the analysis using whichever (remaining) allocation size is passed the first time the phi node is visited. If it is later visited with a smaller remaining size, which may lead to out of bounds accesses, it will not be detected. Fix this by keeping track of the smallest seen remaining allocation size and redo the analysis if it is decreased. To avoid degenerate cases (including via loops), limit the number of allowed decreases to a small number.
89 lines
2.7 KiB
LLVM
89 lines
2.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
|
|
|
|
define void @test_phi_diff_size(i1 %c) sspstrong {
|
|
; CHECK-LABEL: test_phi_diff_size:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: subq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: movq %fs:40, %rax
|
|
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: je .LBB0_1
|
|
; CHECK-NEXT: # %bb.2: # %if
|
|
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rax
|
|
; CHECK-NEXT: jmp .LBB0_3
|
|
; CHECK-NEXT: .LBB0_1:
|
|
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rax
|
|
; CHECK-NEXT: .LBB0_3: # %join
|
|
; CHECK-NEXT: movq $0, (%rax)
|
|
; CHECK-NEXT: movq %fs:40, %rax
|
|
; CHECK-NEXT: cmpq {{[0-9]+}}(%rsp), %rax
|
|
; CHECK-NEXT: jne .LBB0_5
|
|
; CHECK-NEXT: # %bb.4: # %SP_return
|
|
; CHECK-NEXT: addq $24, %rsp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB0_5: # %CallStackCheckFailBlk
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: callq __stack_chk_fail@PLT
|
|
entry:
|
|
%a = alloca i64
|
|
br i1 %c, label %if, label %join
|
|
|
|
if:
|
|
%gep = getelementptr i8, ptr %a, i64 4
|
|
br label %join
|
|
|
|
join:
|
|
%phi = phi ptr [ %a, %entry ], [ %gep, %if ]
|
|
store i64 0, ptr %phi
|
|
ret void
|
|
}
|
|
|
|
define void @test_phi_loop(i1 %c) sspstrong {
|
|
; CHECK-LABEL: test_phi_loop:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: andq $-131072, %rsp # imm = 0xFFFE0000
|
|
; CHECK-NEXT: subq $262144, %rsp # imm = 0x40000
|
|
; CHECK-NEXT: movq %fs:40, %rax
|
|
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: movq %rsp, %rax
|
|
; CHECK-NEXT: .p2align 4
|
|
; CHECK-NEXT: .LBB1_1: # %loop
|
|
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: movq $0, (%rax)
|
|
; CHECK-NEXT: addq $4, %rax
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: jne .LBB1_1
|
|
; CHECK-NEXT: # %bb.2: # %exit
|
|
; CHECK-NEXT: movq %fs:40, %rax
|
|
; CHECK-NEXT: cmpq {{[0-9]+}}(%rsp), %rax
|
|
; CHECK-NEXT: jne .LBB1_4
|
|
; CHECK-NEXT: # %bb.3: # %SP_return
|
|
; CHECK-NEXT: movq %rbp, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB1_4: # %CallStackCheckFailBlk
|
|
; CHECK-NEXT: .cfi_def_cfa %rbp, 16
|
|
; CHECK-NEXT: callq __stack_chk_fail@PLT
|
|
entry:
|
|
%a = alloca <10000 x i64>
|
|
br label %loop
|
|
|
|
loop:
|
|
%phi = phi ptr [ %a, %entry ], [ %gep, %loop ]
|
|
store i64 0, ptr %phi
|
|
%gep = getelementptr i8, ptr %phi, i64 4
|
|
br i1 %c, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|