Files
clang-p2996/llvm/test/CodeGen/X86/probe-stack-eflags.ll
Tim Northover b32280baf9 X86: relax EFLAGS liveness check when generating stack probes.
The probes are all inserted at the iterator passed into the functions, so
that's where any EFLAGS clobbering will happen and where we need it to be dead.

Fixes: https://github.com/llvm/llvm-project/issues/59121
2022-11-30 11:44:39 +00:00

116 lines
3.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s | FileCheck %s
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; https://github.com/llvm/llvm-project/issues/49509
; Stack probes must not clobber live EFLAGS. Previously, the prologue was
; inserted in %bb.2, with "subq $8, %rsp" clobbering the "sets %bl" flag.
define i32 @f(i32 %a, i32 %b) #0 {
; CHECK-LABEL: f:
; CHECK: # %bb.0: # %bb13.i
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: je .LBB0_1
; CHECK-NEXT: # %bb.2: # %bb16.i
; CHECK-NEXT: sets %bl
; CHECK-NEXT: testl %esi, %esi
; CHECK-NEXT: sets %bpl
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: callq *%rax
; CHECK-NEXT: movb $1, %al
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: xorb %bpl, %bl
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: xorb $1, %bl
; CHECK-NEXT: movzbl %bl, %eax
; CHECK-NEXT: jmp .LBB0_3
; CHECK-NEXT: .LBB0_1:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: .LBB0_3: # %exit2
; CHECK-NEXT: addq $8, %rsp
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
bb13.i:
%0 = icmp eq i32 %a, 0
br i1 %0, label %exit2, label %bb16.i
bb16.i: ; preds = %bb13.i
%1 = icmp slt i32 %a, 0
%2 = icmp slt i32 %b, 0
%sign_z.i = xor i1 %1, %2
br label %exit1
exit1: ; preds = %bb16.i
%3 = call { i64, i64 } null()
%4 = icmp eq i64 0, 0
br i1 %4, label %bb41.i, label %bb33.i
bb33.i: ; preds = %exit1
%rcarry.not.i = icmp ult i64 0, 0
br label %bb41.i
bb41.i: ; preds = %bb33.i, %exit1
br label %bb62.i
bb62.i: ; preds = %bb41.i
%_109.not.i = icmp eq i8 0, 0
br i1 %_109.not.i, label %bb70.i, label %bb64.i
bb64.i: ; preds = %bb62.i
%5 = icmp ne i64 0, 0
br label %bb70.i
bb70.i: ; preds = %bb64.i, %bb62.i
%spec.select.i.i = select i1 %sign_z.i, i32 0, i32 1
br label %exit2
exit2: ; preds = %bb70.i, %bb13.i
%.1.i = phi i32 [ %spec.select.i.i, %bb70.i ], [ 0, %bb13.i ]
ret i32 %.1.i
}
define void @CSE_eflags_live(i64 %length) "probe-stack"="__chkstk_darwin" {
; CHECK-LABEL: CSE_eflags_live:
; 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: testq %rdi, %rdi
; CHECK-NEXT: je .LBB1_2
; CHECK-NEXT: # %bb.1: # %if.end6
; CHECK-NEXT: movq $-1, %rax
; CHECK-NEXT: cmovnsq %rdi, %rax
; CHECK-NEXT: addq $15, %rax
; CHECK-NEXT: andq $-16, %rax
; CHECK-NEXT: callq __chkstk_darwin
; CHECK-NEXT: subq %rax, %rsp
; CHECK-NEXT: .LBB1_2: # %cleanup78
; CHECK-NEXT: movq %rbp, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: retq
entry:
%cmp4 = icmp eq i64 %length, 0
br i1 %cmp4, label %cleanup78, label %if.end6
if.end6:
%0 = tail call i64 @llvm.smax.i64(i64 %length, i64 -1)
%vla = alloca i8, i64 %0, align 16
br label %cleanup78
cleanup78:
ret void
}
declare i64 @llvm.smax.i64(i64, i64)
attributes #0 = { nounwind "probe-stack"="inline-asm" }