You've already forked linux-packaging-mono
Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
parent
e9207cf623
commit
ef583813eb
@@ -10,16 +10,10 @@ define i64 @test_add_i64(i64 %arg1, i64 %arg2) {
|
||||
;
|
||||
; X32-LABEL: test_add_i64:
|
||||
; X32: # %bb.0:
|
||||
; X32-NEXT: pushl %ebp
|
||||
; X32-NEXT: .cfi_def_cfa_offset 8
|
||||
; X32-NEXT: .cfi_offset %ebp, -8
|
||||
; X32-NEXT: movl %esp, %ebp
|
||||
; X32-NEXT: .cfi_def_cfa_register %ebp
|
||||
; X32-NEXT: movl 16(%ebp), %eax
|
||||
; X32-NEXT: movl 20(%ebp), %edx
|
||||
; X32-NEXT: addl 8(%ebp), %eax
|
||||
; X32-NEXT: adcl 12(%ebp), %edx
|
||||
; X32-NEXT: popl %ebp
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx
|
||||
; X32-NEXT: retl
|
||||
%ret = add i64 %arg1, %arg2
|
||||
ret i64 %ret
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
; CHECK-NEXT: X86 PIC Global Base Reg Initialization
|
||||
; CHECK-NEXT: Expand ISel Pseudo-instructions
|
||||
; CHECK-NEXT: Local Stack Slot Allocation
|
||||
; CHECK-NEXT: MachineDominator Tree Construction
|
||||
; CHECK-NEXT: X86 EFLAGS copy lowering
|
||||
; CHECK-NEXT: X86 WinAlloca Expander
|
||||
; CHECK-NEXT: Eliminate PHI nodes for register allocation
|
||||
; CHECK-NEXT: Two-Address instruction pass
|
||||
|
||||
37
external/llvm/test/CodeGen/X86/clobber-fi0.ll
vendored
37
external/llvm/test/CodeGen/X86/clobber-fi0.ll
vendored
@@ -1,37 +0,0 @@
|
||||
; RUN: llc < %s -verify-machineinstrs -mcpu=generic -mtriple=x86_64-linux | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.7.0"
|
||||
|
||||
; In the code below we need to copy the EFLAGS because of scheduling constraints.
|
||||
; When copying the EFLAGS we need to write to the stack with push/pop. This forces
|
||||
; us to emit the prolog.
|
||||
|
||||
; CHECK: main
|
||||
; CHECK: subq{{.*}}rsp
|
||||
; CHECK: ret
|
||||
define i32 @main(i32 %arg, i8** %arg1) nounwind {
|
||||
bb:
|
||||
%tmp = alloca i32, align 4 ; [#uses=3 type=i32*]
|
||||
%tmp2 = alloca i32, align 4 ; [#uses=3 type=i32*]
|
||||
%tmp3 = alloca i32 ; [#uses=1 type=i32*]
|
||||
store volatile i32 1, i32* %tmp, align 4
|
||||
store volatile i32 1, i32* %tmp2, align 4
|
||||
br label %bb4
|
||||
|
||||
bb4: ; preds = %bb4, %bb
|
||||
%tmp6 = load volatile i32, i32* %tmp2, align 4 ; [#uses=1 type=i32]
|
||||
%tmp7 = add i32 %tmp6, -1 ; [#uses=2 type=i32]
|
||||
store volatile i32 %tmp7, i32* %tmp2, align 4
|
||||
%tmp8 = icmp eq i32 %tmp7, 0 ; [#uses=1 type=i1]
|
||||
%tmp9 = load volatile i32, i32* %tmp ; [#uses=1 type=i32]
|
||||
%tmp10 = add i32 %tmp9, -1 ; [#uses=1 type=i32]
|
||||
store volatile i32 %tmp10, i32* %tmp3
|
||||
br i1 %tmp8, label %bb11, label %bb4
|
||||
|
||||
bb11: ; preds = %bb4
|
||||
%tmp12 = load volatile i32, i32* %tmp, align 4 ; [#uses=1 type=i32]
|
||||
ret i32 %tmp12
|
||||
}
|
||||
|
||||
|
||||
@@ -1,100 +1,110 @@
|
||||
; RUN: llc -mtriple=i386-linux-gnu %s -o - | FileCheck %s -check-prefix=i386
|
||||
; RUN: llc -mtriple=i386-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=i386f
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=i386-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=32-ALL,32-GOOD-RA
|
||||
; RUN: llc -mtriple=i386-linux-gnu -verify-machineinstrs -pre-RA-sched=fast %s -o - | FileCheck %s --check-prefixes=32-ALL,32-FAST-RA
|
||||
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu %s -o - | FileCheck %s -check-prefix=x8664
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf %s -o - | FileCheck %s -check-prefix=x8664-sahf
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664-sahf
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -mcpu=corei7 %s -o - | FileCheck %s -check-prefix=x8664-sahf
|
||||
|
||||
; TODO: Reenable verify-machineinstr once the if (!AXDead) // FIXME
|
||||
; in X86InstrInfo::copyPhysReg() is resolved.
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=64-ALL,64-GOOD-RA
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs -pre-RA-sched=fast %s -o - | FileCheck %s --check-prefixes=64-ALL,64-FAST-RA
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs -mattr=+sahf %s -o - | FileCheck %s --check-prefixes=64-ALL,64-GOOD-RA-SAHF
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs -mattr=+sahf -pre-RA-sched=fast %s -o - | FileCheck %s --check-prefixes=64-ALL,64-FAST-RA-SAHF
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs -mcpu=corei7 %s -o - | FileCheck %s --check-prefixes=64-ALL,64-GOOD-RA-SAHF
|
||||
|
||||
declare i32 @foo()
|
||||
declare i32 @bar(i64)
|
||||
|
||||
define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) {
|
||||
; i386-LABEL: test_intervening_call:
|
||||
; i386: cmpxchg8b
|
||||
; i386-NEXT: pushl %eax
|
||||
; i386-NEXT: seto %al
|
||||
; i386-NEXT: lahf
|
||||
; i386-NEXT: movl %eax, [[FLAGS:%.*]]
|
||||
; i386-NEXT: popl %eax
|
||||
; i386-NEXT: subl $8, %esp
|
||||
; i386-NEXT: pushl %edx
|
||||
; i386-NEXT: pushl %eax
|
||||
; i386-NEXT: calll bar
|
||||
; i386-NEXT: addl $16, %esp
|
||||
; i386-NEXT: movl [[FLAGS]], %eax
|
||||
; i386-NEXT: addb $127, %al
|
||||
; i386-NEXT: sahf
|
||||
; i386-NEXT: jne
|
||||
|
||||
; In the following case we get a long chain of EFLAGS save/restore due to
|
||||
; a sequence of:
|
||||
; In the following case when using fast scheduling we get a long chain of
|
||||
; EFLAGS save/restore due to a sequence of:
|
||||
; cmpxchg8b (implicit-def eflags)
|
||||
; eax = copy eflags
|
||||
; adjcallstackdown32
|
||||
; ...
|
||||
; use of eax
|
||||
; During PEI the adjcallstackdown32 is replaced with the subl which
|
||||
; clobbers eflags, effectively interfering in the liveness interval.
|
||||
; Is this a case we care about? Maybe no, considering this issue
|
||||
; happens with the fast pre-regalloc scheduler enforced. A more
|
||||
; performant scheduler would move the adjcallstackdown32 out of the
|
||||
; eflags liveness interval.
|
||||
|
||||
; i386f-LABEL: test_intervening_call:
|
||||
; i386f: cmpxchg8b
|
||||
; i386f-NEXT: pushl %eax
|
||||
; i386f-NEXT: seto %al
|
||||
; i386f-NEXT: lahf
|
||||
; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
|
||||
; i386f-NEXT: popl %eax
|
||||
; i386f-NEXT: subl $8, %esp
|
||||
; i386f-NEXT: pushl %eax
|
||||
; i386f-NEXT: movl %ecx, %eax
|
||||
; i386f-NEXT: addb $127, %al
|
||||
; i386f-NEXT: sahf
|
||||
; i386f-NEXT: popl %eax
|
||||
; i386f-NEXT: pushl %eax
|
||||
; i386f-NEXT: seto %al
|
||||
; i386f-NEXT: lahf
|
||||
; i386f-NEXT: movl %eax, %esi
|
||||
; i386f-NEXT: popl %eax
|
||||
; i386f-NEXT: pushl %edx
|
||||
; i386f-NEXT: pushl %eax
|
||||
; i386f-NEXT: calll bar
|
||||
; i386f-NEXT: addl $16, %esp
|
||||
; i386f-NEXT: movl %esi, %eax
|
||||
; i386f-NEXT: addb $127, %al
|
||||
|
||||
; x8664-LABEL: test_intervening_call:
|
||||
; x8664: cmpxchgq
|
||||
; x8664: pushfq
|
||||
; x8664-NEXT: popq [[FLAGS:%.*]]
|
||||
; x8664-NEXT: movq %rax, %rdi
|
||||
; x8664-NEXT: callq bar
|
||||
; x8664-NEXT: pushq [[FLAGS]]
|
||||
; x8664-NEXT: popfq
|
||||
; x8664-NEXT: jne
|
||||
|
||||
; x8664-sahf-LABEL: test_intervening_call:
|
||||
; x8664-sahf: cmpxchgq
|
||||
; x8664-sahf: pushq %rax
|
||||
; x8664-sahf-NEXT: seto %al
|
||||
; x8664-sahf-NEXT: lahf
|
||||
; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
|
||||
; x8664-sahf-NEXT: popq %rax
|
||||
; x8664-sahf-NEXT: movq %rax, %rdi
|
||||
; x8664-sahf-NEXT: callq bar
|
||||
; RAX is dead, no need to push and pop it.
|
||||
; x8664-sahf-NEXT: movq [[FLAGS]], %rax
|
||||
; x8664-sahf-NEXT: addb $127, %al
|
||||
; x8664-sahf-NEXT: sahf
|
||||
; x8664-sahf-NEXT: jne
|
||||
|
||||
; clobbers eflags, effectively interfering in the liveness interval. However,
|
||||
; we then promote these copies into independent conditions in GPRs that avoids
|
||||
; repeated saving and restoring logic and can be trivially managed by the
|
||||
; register allocator.
|
||||
define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) nounwind {
|
||||
; 32-GOOD-RA-LABEL: test_intervening_call:
|
||||
; 32-GOOD-RA: # %bb.0: # %entry
|
||||
; 32-GOOD-RA-NEXT: pushl %ebx
|
||||
; 32-GOOD-RA-NEXT: pushl %esi
|
||||
; 32-GOOD-RA-NEXT: pushl %eax
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; 32-GOOD-RA-NEXT: lock cmpxchg8b (%esi)
|
||||
; 32-GOOD-RA-NEXT: setne %bl
|
||||
; 32-GOOD-RA-NEXT: subl $8, %esp
|
||||
; 32-GOOD-RA-NEXT: pushl %edx
|
||||
; 32-GOOD-RA-NEXT: pushl %eax
|
||||
; 32-GOOD-RA-NEXT: calll bar
|
||||
; 32-GOOD-RA-NEXT: addl $16, %esp
|
||||
; 32-GOOD-RA-NEXT: testb %bl, %bl
|
||||
; 32-GOOD-RA-NEXT: jne .LBB0_3
|
||||
; 32-GOOD-RA-NEXT: # %bb.1: # %t
|
||||
; 32-GOOD-RA-NEXT: movl $42, %eax
|
||||
; 32-GOOD-RA-NEXT: jmp .LBB0_2
|
||||
; 32-GOOD-RA-NEXT: .LBB0_3: # %f
|
||||
; 32-GOOD-RA-NEXT: xorl %eax, %eax
|
||||
; 32-GOOD-RA-NEXT: .LBB0_2: # %t
|
||||
; 32-GOOD-RA-NEXT: xorl %edx, %edx
|
||||
; 32-GOOD-RA-NEXT: addl $4, %esp
|
||||
; 32-GOOD-RA-NEXT: popl %esi
|
||||
; 32-GOOD-RA-NEXT: popl %ebx
|
||||
; 32-GOOD-RA-NEXT: retl
|
||||
;
|
||||
; 32-FAST-RA-LABEL: test_intervening_call:
|
||||
; 32-FAST-RA: # %bb.0: # %entry
|
||||
; 32-FAST-RA-NEXT: pushl %ebx
|
||||
; 32-FAST-RA-NEXT: pushl %esi
|
||||
; 32-FAST-RA-NEXT: pushl %eax
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; 32-FAST-RA-NEXT: lock cmpxchg8b (%esi)
|
||||
; 32-FAST-RA-NEXT: setne %bl
|
||||
; 32-FAST-RA-NEXT: subl $8, %esp
|
||||
; 32-FAST-RA-NEXT: pushl %edx
|
||||
; 32-FAST-RA-NEXT: pushl %eax
|
||||
; 32-FAST-RA-NEXT: calll bar
|
||||
; 32-FAST-RA-NEXT: addl $16, %esp
|
||||
; 32-FAST-RA-NEXT: testb %bl, %bl
|
||||
; 32-FAST-RA-NEXT: jne .LBB0_3
|
||||
; 32-FAST-RA-NEXT: # %bb.1: # %t
|
||||
; 32-FAST-RA-NEXT: movl $42, %eax
|
||||
; 32-FAST-RA-NEXT: jmp .LBB0_2
|
||||
; 32-FAST-RA-NEXT: .LBB0_3: # %f
|
||||
; 32-FAST-RA-NEXT: xorl %eax, %eax
|
||||
; 32-FAST-RA-NEXT: .LBB0_2: # %t
|
||||
; 32-FAST-RA-NEXT: xorl %edx, %edx
|
||||
; 32-FAST-RA-NEXT: addl $4, %esp
|
||||
; 32-FAST-RA-NEXT: popl %esi
|
||||
; 32-FAST-RA-NEXT: popl %ebx
|
||||
; 32-FAST-RA-NEXT: retl
|
||||
;
|
||||
; 64-ALL-LABEL: test_intervening_call:
|
||||
; 64-ALL: # %bb.0: # %entry
|
||||
; 64-ALL-NEXT: pushq %rbx
|
||||
; 64-ALL-NEXT: movq %rsi, %rax
|
||||
; 64-ALL-NEXT: lock cmpxchgq %rdx, (%rdi)
|
||||
; 64-ALL-NEXT: setne %bl
|
||||
; 64-ALL-NEXT: movq %rax, %rdi
|
||||
; 64-ALL-NEXT: callq bar
|
||||
; 64-ALL-NEXT: testb %bl, %bl
|
||||
; 64-ALL-NEXT: jne .LBB0_2
|
||||
; 64-ALL-NEXT: # %bb.1: # %t
|
||||
; 64-ALL-NEXT: movl $42, %eax
|
||||
; 64-ALL-NEXT: popq %rbx
|
||||
; 64-ALL-NEXT: retq
|
||||
; 64-ALL-NEXT: .LBB0_2: # %f
|
||||
; 64-ALL-NEXT: xorl %eax, %eax
|
||||
; 64-ALL-NEXT: popq %rbx
|
||||
; 64-ALL-NEXT: retq
|
||||
entry:
|
||||
%cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
|
||||
%v = extractvalue { i64, i1 } %cx, 0
|
||||
%p = extractvalue { i64, i1 } %cx, 1
|
||||
@@ -109,23 +119,62 @@ f:
|
||||
}
|
||||
|
||||
; Interesting in producing a clobber without any function calls.
|
||||
define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) {
|
||||
; i386-LABEL: test_control_flow:
|
||||
; i386: cmpxchg
|
||||
; i386-NEXT: jne
|
||||
|
||||
; i386f-LABEL: test_control_flow:
|
||||
; i386f: cmpxchg
|
||||
; i386f-NEXT: jne
|
||||
|
||||
; x8664-LABEL: test_control_flow:
|
||||
; x8664: cmpxchg
|
||||
; x8664-NEXT: jne
|
||||
|
||||
; x8664-sahf-LABEL: test_control_flow:
|
||||
; x8664-sahf: cmpxchg
|
||||
; x8664-sahf-NEXT: jne
|
||||
|
||||
define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) nounwind {
|
||||
; 32-ALL-LABEL: test_control_flow:
|
||||
; 32-ALL: # %bb.0: # %entry
|
||||
; 32-ALL-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; 32-ALL-NEXT: cmpl {{[0-9]+}}(%esp), %eax
|
||||
; 32-ALL-NEXT: jle .LBB1_6
|
||||
; 32-ALL-NEXT: # %bb.1: # %loop_start
|
||||
; 32-ALL-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; 32-ALL-NEXT: .p2align 4, 0x90
|
||||
; 32-ALL-NEXT: .LBB1_2: # %while.condthread-pre-split.i
|
||||
; 32-ALL-NEXT: # =>This Loop Header: Depth=1
|
||||
; 32-ALL-NEXT: # Child Loop BB1_3 Depth 2
|
||||
; 32-ALL-NEXT: movl (%ecx), %edx
|
||||
; 32-ALL-NEXT: .p2align 4, 0x90
|
||||
; 32-ALL-NEXT: .LBB1_3: # %while.cond.i
|
||||
; 32-ALL-NEXT: # Parent Loop BB1_2 Depth=1
|
||||
; 32-ALL-NEXT: # => This Inner Loop Header: Depth=2
|
||||
; 32-ALL-NEXT: movl %edx, %eax
|
||||
; 32-ALL-NEXT: xorl %edx, %edx
|
||||
; 32-ALL-NEXT: testl %eax, %eax
|
||||
; 32-ALL-NEXT: je .LBB1_3
|
||||
; 32-ALL-NEXT: # %bb.4: # %while.body.i
|
||||
; 32-ALL-NEXT: # in Loop: Header=BB1_2 Depth=1
|
||||
; 32-ALL-NEXT: lock cmpxchgl %eax, (%ecx)
|
||||
; 32-ALL-NEXT: jne .LBB1_2
|
||||
; 32-ALL-NEXT: # %bb.5:
|
||||
; 32-ALL-NEXT: xorl %eax, %eax
|
||||
; 32-ALL-NEXT: .LBB1_6: # %cond.end
|
||||
; 32-ALL-NEXT: retl
|
||||
;
|
||||
; 64-ALL-LABEL: test_control_flow:
|
||||
; 64-ALL: # %bb.0: # %entry
|
||||
; 64-ALL-NEXT: cmpl %edx, %esi
|
||||
; 64-ALL-NEXT: jle .LBB1_5
|
||||
; 64-ALL-NEXT: .p2align 4, 0x90
|
||||
; 64-ALL-NEXT: .LBB1_1: # %while.condthread-pre-split.i
|
||||
; 64-ALL-NEXT: # =>This Loop Header: Depth=1
|
||||
; 64-ALL-NEXT: # Child Loop BB1_2 Depth 2
|
||||
; 64-ALL-NEXT: movl (%rdi), %ecx
|
||||
; 64-ALL-NEXT: .p2align 4, 0x90
|
||||
; 64-ALL-NEXT: .LBB1_2: # %while.cond.i
|
||||
; 64-ALL-NEXT: # Parent Loop BB1_1 Depth=1
|
||||
; 64-ALL-NEXT: # => This Inner Loop Header: Depth=2
|
||||
; 64-ALL-NEXT: movl %ecx, %eax
|
||||
; 64-ALL-NEXT: xorl %ecx, %ecx
|
||||
; 64-ALL-NEXT: testl %eax, %eax
|
||||
; 64-ALL-NEXT: je .LBB1_2
|
||||
; 64-ALL-NEXT: # %bb.3: # %while.body.i
|
||||
; 64-ALL-NEXT: # in Loop: Header=BB1_1 Depth=1
|
||||
; 64-ALL-NEXT: lock cmpxchgl %eax, (%rdi)
|
||||
; 64-ALL-NEXT: jne .LBB1_1
|
||||
; 64-ALL-NEXT: # %bb.4:
|
||||
; 64-ALL-NEXT: xorl %esi, %esi
|
||||
; 64-ALL-NEXT: .LBB1_5: # %cond.end
|
||||
; 64-ALL-NEXT: movl %esi, %eax
|
||||
; 64-ALL-NEXT: retq
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %i, %j
|
||||
br i1 %cmp, label %loop_start, label %cond.end
|
||||
@@ -158,52 +207,68 @@ cond.end:
|
||||
|
||||
; This one is an interesting case because CMOV doesn't have a chain
|
||||
; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here.
|
||||
define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) {
|
||||
; i386-LABEL: test_feed_cmov:
|
||||
; i386: cmpxchgl
|
||||
; i386-NEXT: seto %al
|
||||
; i386-NEXT: lahf
|
||||
; i386-NEXT: movl %eax, [[FLAGS:%.*]]
|
||||
; i386-NEXT: calll foo
|
||||
; i386-NEXT: pushl %eax
|
||||
; i386-NEXT: movl [[FLAGS]], %eax
|
||||
; i386-NEXT: addb $127, %al
|
||||
; i386-NEXT: sahf
|
||||
; i386-NEXT: popl %eax
|
||||
|
||||
; i386f-LABEL: test_feed_cmov:
|
||||
; i386f: cmpxchgl
|
||||
; i386f-NEXT: seto %al
|
||||
; i386f-NEXT: lahf
|
||||
; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
|
||||
; i386f-NEXT: calll foo
|
||||
; i386f-NEXT: pushl %eax
|
||||
; i386f-NEXT: movl [[FLAGS]], %eax
|
||||
; i386f-NEXT: addb $127, %al
|
||||
; i386f-NEXT: sahf
|
||||
; i386f-NEXT: popl %eax
|
||||
|
||||
; x8664-LABEL: test_feed_cmov:
|
||||
; x8664: cmpxchg
|
||||
; x8664: pushfq
|
||||
; x8664-NEXT: popq [[FLAGS:%.*]]
|
||||
; x8664-NEXT: callq foo
|
||||
; x8664-NEXT: pushq [[FLAGS]]
|
||||
; x8664-NEXT: popfq
|
||||
|
||||
; x8664-sahf-LABEL: test_feed_cmov:
|
||||
; x8664-sahf: cmpxchgl
|
||||
; RAX is dead, do not push or pop it.
|
||||
; x8664-sahf-NEXT: seto %al
|
||||
; x8664-sahf-NEXT: lahf
|
||||
; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
|
||||
; x8664-sahf-NEXT: callq foo
|
||||
; x8664-sahf-NEXT: pushq %rax
|
||||
; x8664-sahf-NEXT: movq [[FLAGS]], %rax
|
||||
; x8664-sahf-NEXT: addb $127, %al
|
||||
; x8664-sahf-NEXT: sahf
|
||||
; x8664-sahf-NEXT: popq %rax
|
||||
|
||||
define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) nounwind {
|
||||
; 32-GOOD-RA-LABEL: test_feed_cmov:
|
||||
; 32-GOOD-RA: # %bb.0: # %entry
|
||||
; 32-GOOD-RA-NEXT: pushl %ebx
|
||||
; 32-GOOD-RA-NEXT: pushl %esi
|
||||
; 32-GOOD-RA-NEXT: pushl %eax
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; 32-GOOD-RA-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; 32-GOOD-RA-NEXT: lock cmpxchgl %esi, (%ecx)
|
||||
; 32-GOOD-RA-NEXT: sete %bl
|
||||
; 32-GOOD-RA-NEXT: calll foo
|
||||
; 32-GOOD-RA-NEXT: testb %bl, %bl
|
||||
; 32-GOOD-RA-NEXT: jne .LBB2_2
|
||||
; 32-GOOD-RA-NEXT: # %bb.1: # %entry
|
||||
; 32-GOOD-RA-NEXT: movl %eax, %esi
|
||||
; 32-GOOD-RA-NEXT: .LBB2_2: # %entry
|
||||
; 32-GOOD-RA-NEXT: movl %esi, %eax
|
||||
; 32-GOOD-RA-NEXT: addl $4, %esp
|
||||
; 32-GOOD-RA-NEXT: popl %esi
|
||||
; 32-GOOD-RA-NEXT: popl %ebx
|
||||
; 32-GOOD-RA-NEXT: retl
|
||||
;
|
||||
; 32-FAST-RA-LABEL: test_feed_cmov:
|
||||
; 32-FAST-RA: # %bb.0: # %entry
|
||||
; 32-FAST-RA-NEXT: pushl %ebx
|
||||
; 32-FAST-RA-NEXT: pushl %esi
|
||||
; 32-FAST-RA-NEXT: pushl %eax
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; 32-FAST-RA-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; 32-FAST-RA-NEXT: lock cmpxchgl %esi, (%ecx)
|
||||
; 32-FAST-RA-NEXT: sete %bl
|
||||
; 32-FAST-RA-NEXT: calll foo
|
||||
; 32-FAST-RA-NEXT: testb %bl, %bl
|
||||
; 32-FAST-RA-NEXT: jne .LBB2_2
|
||||
; 32-FAST-RA-NEXT: # %bb.1: # %entry
|
||||
; 32-FAST-RA-NEXT: movl %eax, %esi
|
||||
; 32-FAST-RA-NEXT: .LBB2_2: # %entry
|
||||
; 32-FAST-RA-NEXT: movl %esi, %eax
|
||||
; 32-FAST-RA-NEXT: addl $4, %esp
|
||||
; 32-FAST-RA-NEXT: popl %esi
|
||||
; 32-FAST-RA-NEXT: popl %ebx
|
||||
; 32-FAST-RA-NEXT: retl
|
||||
;
|
||||
; 64-ALL-LABEL: test_feed_cmov:
|
||||
; 64-ALL: # %bb.0: # %entry
|
||||
; 64-ALL-NEXT: pushq %rbp
|
||||
; 64-ALL-NEXT: pushq %rbx
|
||||
; 64-ALL-NEXT: pushq %rax
|
||||
; 64-ALL-NEXT: movl %edx, %ebx
|
||||
; 64-ALL-NEXT: movl %esi, %eax
|
||||
; 64-ALL-NEXT: lock cmpxchgl %ebx, (%rdi)
|
||||
; 64-ALL-NEXT: sete %bpl
|
||||
; 64-ALL-NEXT: callq foo
|
||||
; 64-ALL-NEXT: testb %bpl, %bpl
|
||||
; 64-ALL-NEXT: cmovnel %ebx, %eax
|
||||
; 64-ALL-NEXT: addq $8, %rsp
|
||||
; 64-ALL-NEXT: popq %rbx
|
||||
; 64-ALL-NEXT: popq %rbp
|
||||
; 64-ALL-NEXT: retq
|
||||
entry:
|
||||
%res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
|
||||
%success = extractvalue { i32, i1 } %res, 1
|
||||
|
||||
|
||||
357
external/llvm/test/CodeGen/X86/copy-eflags.ll
vendored
357
external/llvm/test/CodeGen/X86/copy-eflags.ll
vendored
@@ -1,6 +1,8 @@
|
||||
; RUN: llc -o - %s | FileCheck %s
|
||||
; This tests for the problem originally reported in http://llvm.org/PR25951
|
||||
target triple = "i686-unknown-linux-gnu"
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -o - -mtriple=i686-unknown-unknown %s | FileCheck %s --check-prefixes=ALL,X32
|
||||
; RUN: llc -o - -mtriple=x86_64-unknown-unknown %s | FileCheck %s --check-prefixes=ALL,X64
|
||||
;
|
||||
; Test patterns that require preserving and restoring flags.
|
||||
|
||||
@b = common global i8 0, align 1
|
||||
@c = common global i32 0, align 4
|
||||
@@ -8,13 +10,61 @@ target triple = "i686-unknown-linux-gnu"
|
||||
@d = common global i8 0, align 1
|
||||
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||
|
||||
; CHECK-LABEL: func:
|
||||
; This tests whether eax is properly saved/restored around the
|
||||
; lahf/sahf instruction sequences. We make mem op volatile to prevent
|
||||
; their reordering to avoid spills.
|
||||
declare void @external(i32)
|
||||
|
||||
|
||||
define i32 @func() {
|
||||
; A test that re-uses flags in interesting ways due to volatile accesses.
|
||||
; Specifically, the first increment's flags are reused for the branch despite
|
||||
; being clobbered by the second increment.
|
||||
define i32 @test1() nounwind {
|
||||
; X32-LABEL: test1:
|
||||
; X32: # %bb.0: # %entry
|
||||
; X32-NEXT: movb b, %cl
|
||||
; X32-NEXT: movl %ecx, %eax
|
||||
; X32-NEXT: incb %al
|
||||
; X32-NEXT: movb %al, b
|
||||
; X32-NEXT: incl c
|
||||
; X32-NEXT: sete %dl
|
||||
; X32-NEXT: movb a, %ah
|
||||
; X32-NEXT: movb %ah, %ch
|
||||
; X32-NEXT: incb %ch
|
||||
; X32-NEXT: cmpb %cl, %ah
|
||||
; X32-NEXT: sete d
|
||||
; X32-NEXT: movb %ch, a
|
||||
; X32-NEXT: testb %dl, %dl
|
||||
; X32-NEXT: jne .LBB0_2
|
||||
; X32-NEXT: # %bb.1: # %if.then
|
||||
; X32-NEXT: movsbl %al, %eax
|
||||
; X32-NEXT: pushl %eax
|
||||
; X32-NEXT: calll external
|
||||
; X32-NEXT: addl $4, %esp
|
||||
; X32-NEXT: .LBB0_2: # %if.end
|
||||
; X32-NEXT: xorl %eax, %eax
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: test1:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: movb {{.*}}(%rip), %dil
|
||||
; X64-NEXT: movl %edi, %eax
|
||||
; X64-NEXT: incb %al
|
||||
; X64-NEXT: movb %al, {{.*}}(%rip)
|
||||
; X64-NEXT: incl {{.*}}(%rip)
|
||||
; X64-NEXT: sete %sil
|
||||
; X64-NEXT: movb {{.*}}(%rip), %cl
|
||||
; X64-NEXT: movl %ecx, %edx
|
||||
; X64-NEXT: incb %dl
|
||||
; X64-NEXT: cmpb %dil, %cl
|
||||
; X64-NEXT: sete {{.*}}(%rip)
|
||||
; X64-NEXT: movb %dl, {{.*}}(%rip)
|
||||
; X64-NEXT: testb %sil, %sil
|
||||
; X64-NEXT: jne .LBB0_2
|
||||
; X64-NEXT: # %bb.1: # %if.then
|
||||
; X64-NEXT: pushq %rax
|
||||
; X64-NEXT: movsbl %al, %edi
|
||||
; X64-NEXT: callq external
|
||||
; X64-NEXT: addq $8, %rsp
|
||||
; X64-NEXT: .LBB0_2: # %if.end
|
||||
; X64-NEXT: xorl %eax, %eax
|
||||
; X64-NEXT: retq
|
||||
entry:
|
||||
%bval = load i8, i8* @b
|
||||
%inc = add i8 %bval, 1
|
||||
@@ -25,33 +75,290 @@ entry:
|
||||
%aval = load volatile i8, i8* @a
|
||||
%inc2 = add i8 %aval, 1
|
||||
store volatile i8 %inc2, i8* @a
|
||||
; Copy flags produced by the incb of %inc1 to a register, need to save+restore
|
||||
; eax around it. The flags will be reused by %tobool.
|
||||
; CHECK: pushl %eax
|
||||
; CHECK: seto %al
|
||||
; CHECK: lahf
|
||||
; CHECK: movl %eax, [[REG:%[a-z]+]]
|
||||
; CHECK: popl %eax
|
||||
%cmp = icmp eq i8 %aval, %bval
|
||||
%conv5 = zext i1 %cmp to i8
|
||||
store i8 %conv5, i8* @d
|
||||
%tobool = icmp eq i32 %inc1, 0
|
||||
; We restore flags with an 'addb, sahf' sequence, need to save+restore eax
|
||||
; around it.
|
||||
; CHECK: pushl %eax
|
||||
; CHECK: movl [[REG]], %eax
|
||||
; CHECK: addb $127, %al
|
||||
; CHECK: sahf
|
||||
; CHECK: popl %eax
|
||||
br i1 %tobool, label %if.end, label %if.then
|
||||
|
||||
if.then:
|
||||
%conv6 = sext i8 %inc to i32
|
||||
%call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %conv6)
|
||||
call void @external(i32 %conv6)
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8* nocapture readonly, ...)
|
||||
; Preserve increment flags across a call.
|
||||
define i32 @test2(i32* %ptr) nounwind {
|
||||
; X32-LABEL: test2:
|
||||
; X32: # %bb.0: # %entry
|
||||
; X32-NEXT: pushl %ebx
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: incl (%eax)
|
||||
; X32-NEXT: setne %bl
|
||||
; X32-NEXT: pushl $42
|
||||
; X32-NEXT: calll external
|
||||
; X32-NEXT: addl $4, %esp
|
||||
; X32-NEXT: testb %bl, %bl
|
||||
; X32-NEXT: je .LBB1_1
|
||||
; X32-NEXT: # %bb.2: # %else
|
||||
; X32-NEXT: xorl %eax, %eax
|
||||
; X32-NEXT: popl %ebx
|
||||
; X32-NEXT: retl
|
||||
; X32-NEXT: .LBB1_1: # %then
|
||||
; X32-NEXT: movl $64, %eax
|
||||
; X32-NEXT: popl %ebx
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: test2:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: pushq %rbx
|
||||
; X64-NEXT: incl (%rdi)
|
||||
; X64-NEXT: setne %bl
|
||||
; X64-NEXT: movl $42, %edi
|
||||
; X64-NEXT: callq external
|
||||
; X64-NEXT: testb %bl, %bl
|
||||
; X64-NEXT: je .LBB1_1
|
||||
; X64-NEXT: # %bb.2: # %else
|
||||
; X64-NEXT: xorl %eax, %eax
|
||||
; X64-NEXT: popq %rbx
|
||||
; X64-NEXT: retq
|
||||
; X64-NEXT: .LBB1_1: # %then
|
||||
; X64-NEXT: movl $64, %eax
|
||||
; X64-NEXT: popq %rbx
|
||||
; X64-NEXT: retq
|
||||
entry:
|
||||
%val = load i32, i32* %ptr
|
||||
%inc = add i32 %val, 1
|
||||
store i32 %inc, i32* %ptr
|
||||
%cmp = icmp eq i32 %inc, 0
|
||||
call void @external(i32 42)
|
||||
br i1 %cmp, label %then, label %else
|
||||
|
||||
then:
|
||||
ret i32 64
|
||||
|
||||
else:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare void @external_a()
|
||||
declare void @external_b()
|
||||
|
||||
; This lowers to a conditional tail call instead of a conditional branch. This
|
||||
; is tricky because we can only do this from a leaf function, and so we have to
|
||||
; use volatile stores similar to test1 to force the save and restore of
|
||||
; a condition without calling another function. We then set up subsequent calls
|
||||
; in tail position.
|
||||
define void @test_tail_call(i32* %ptr) nounwind optsize {
|
||||
; X32-LABEL: test_tail_call:
|
||||
; X32: # %bb.0: # %entry
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: incl (%eax)
|
||||
; X32-NEXT: setne %al
|
||||
; X32-NEXT: incb a
|
||||
; X32-NEXT: sete d
|
||||
; X32-NEXT: testb %al, %al
|
||||
; X32-NEXT: jne external_b # TAILCALL
|
||||
; X32-NEXT: # %bb.1: # %then
|
||||
; X32-NEXT: jmp external_a # TAILCALL
|
||||
;
|
||||
; X64-LABEL: test_tail_call:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: incl (%rdi)
|
||||
; X64-NEXT: setne %al
|
||||
; X64-NEXT: incb {{.*}}(%rip)
|
||||
; X64-NEXT: sete {{.*}}(%rip)
|
||||
; X64-NEXT: testb %al, %al
|
||||
; X64-NEXT: jne external_b # TAILCALL
|
||||
; X64-NEXT: # %bb.1: # %then
|
||||
; X64-NEXT: jmp external_a # TAILCALL
|
||||
entry:
|
||||
%val = load i32, i32* %ptr
|
||||
%inc = add i32 %val, 1
|
||||
store i32 %inc, i32* %ptr
|
||||
%cmp = icmp eq i32 %inc, 0
|
||||
%aval = load volatile i8, i8* @a
|
||||
%inc2 = add i8 %aval, 1
|
||||
store volatile i8 %inc2, i8* @a
|
||||
%cmp2 = icmp eq i8 %inc2, 0
|
||||
%conv5 = zext i1 %cmp2 to i8
|
||||
store i8 %conv5, i8* @d
|
||||
br i1 %cmp, label %then, label %else
|
||||
|
||||
then:
|
||||
tail call void @external_a()
|
||||
ret void
|
||||
|
||||
else:
|
||||
tail call void @external_b()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Test a function that gets special select lowering into CFG with copied EFLAGS
|
||||
; threaded across the CFG. This requires our EFLAGS copy rewriting to handle
|
||||
; cross-block rewrites in at least some narrow cases.
|
||||
define void @PR37100(i8 %arg1, i16 %arg2, i64 %arg3, i8 %arg4, i8* %ptr1, i32* %ptr2) {
|
||||
; X32-LABEL: PR37100:
|
||||
; X32: # %bb.0: # %bb
|
||||
; X32-NEXT: pushl %ebp
|
||||
; X32-NEXT: .cfi_def_cfa_offset 8
|
||||
; X32-NEXT: pushl %ebx
|
||||
; X32-NEXT: .cfi_def_cfa_offset 12
|
||||
; X32-NEXT: pushl %edi
|
||||
; X32-NEXT: .cfi_def_cfa_offset 16
|
||||
; X32-NEXT: pushl %esi
|
||||
; X32-NEXT: .cfi_def_cfa_offset 20
|
||||
; X32-NEXT: .cfi_offset %esi, -20
|
||||
; X32-NEXT: .cfi_offset %edi, -16
|
||||
; X32-NEXT: .cfi_offset %ebx, -12
|
||||
; X32-NEXT: .cfi_offset %ebp, -8
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %edi
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; X32-NEXT: movb {{[0-9]+}}(%esp), %ch
|
||||
; X32-NEXT: movb {{[0-9]+}}(%esp), %cl
|
||||
; X32-NEXT: jmp .LBB3_1
|
||||
; X32-NEXT: .p2align 4, 0x90
|
||||
; X32-NEXT: .LBB3_5: # %bb1
|
||||
; X32-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X32-NEXT: xorl %eax, %eax
|
||||
; X32-NEXT: xorl %edx, %edx
|
||||
; X32-NEXT: idivl %ebp
|
||||
; X32-NEXT: .LBB3_1: # %bb1
|
||||
; X32-NEXT: # =>This Inner Loop Header: Depth=1
|
||||
; X32-NEXT: movsbl %cl, %eax
|
||||
; X32-NEXT: movl %eax, %edx
|
||||
; X32-NEXT: sarl $31, %edx
|
||||
; X32-NEXT: cmpl %eax, %esi
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: sbbl %edx, %eax
|
||||
; X32-NEXT: setl %al
|
||||
; X32-NEXT: setl %dl
|
||||
; X32-NEXT: movzbl %dl, %ebp
|
||||
; X32-NEXT: negl %ebp
|
||||
; X32-NEXT: testb %al, %al
|
||||
; X32-NEXT: jne .LBB3_3
|
||||
; X32-NEXT: # %bb.2: # %bb1
|
||||
; X32-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X32-NEXT: movb %ch, %cl
|
||||
; X32-NEXT: .LBB3_3: # %bb1
|
||||
; X32-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X32-NEXT: movb %cl, (%ebx)
|
||||
; X32-NEXT: movl (%edi), %edx
|
||||
; X32-NEXT: testb %al, %al
|
||||
; X32-NEXT: jne .LBB3_5
|
||||
; X32-NEXT: # %bb.4: # %bb1
|
||||
; X32-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X32-NEXT: movl %edx, %ebp
|
||||
; X32-NEXT: jmp .LBB3_5
|
||||
;
|
||||
; X64-LABEL: PR37100:
|
||||
; X64: # %bb.0: # %bb
|
||||
; X64-NEXT: movq %rdx, %r10
|
||||
; X64-NEXT: jmp .LBB3_1
|
||||
; X64-NEXT: .p2align 4, 0x90
|
||||
; X64-NEXT: .LBB3_5: # %bb1
|
||||
; X64-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X64-NEXT: xorl %eax, %eax
|
||||
; X64-NEXT: xorl %edx, %edx
|
||||
; X64-NEXT: idivl %esi
|
||||
; X64-NEXT: .LBB3_1: # %bb1
|
||||
; X64-NEXT: # =>This Inner Loop Header: Depth=1
|
||||
; X64-NEXT: movsbq %dil, %rax
|
||||
; X64-NEXT: xorl %esi, %esi
|
||||
; X64-NEXT: cmpq %rax, %r10
|
||||
; X64-NEXT: setl %sil
|
||||
; X64-NEXT: negl %esi
|
||||
; X64-NEXT: cmpq %rax, %r10
|
||||
; X64-NEXT: jl .LBB3_3
|
||||
; X64-NEXT: # %bb.2: # %bb1
|
||||
; X64-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X64-NEXT: movl %ecx, %edi
|
||||
; X64-NEXT: .LBB3_3: # %bb1
|
||||
; X64-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X64-NEXT: movb %dil, (%r8)
|
||||
; X64-NEXT: jl .LBB3_5
|
||||
; X64-NEXT: # %bb.4: # %bb1
|
||||
; X64-NEXT: # in Loop: Header=BB3_1 Depth=1
|
||||
; X64-NEXT: movl (%r9), %esi
|
||||
; X64-NEXT: jmp .LBB3_5
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1:
|
||||
%tmp = phi i8 [ %tmp8, %bb1 ], [ %arg1, %bb ]
|
||||
%tmp2 = phi i16 [ %tmp12, %bb1 ], [ %arg2, %bb ]
|
||||
%tmp3 = icmp sgt i16 %tmp2, 7
|
||||
%tmp4 = select i1 %tmp3, i16 %tmp2, i16 7
|
||||
%tmp5 = sext i8 %tmp to i64
|
||||
%tmp6 = icmp slt i64 %arg3, %tmp5
|
||||
%tmp7 = sext i1 %tmp6 to i32
|
||||
%tmp8 = select i1 %tmp6, i8 %tmp, i8 %arg4
|
||||
store volatile i8 %tmp8, i8* %ptr1
|
||||
%tmp9 = load volatile i32, i32* %ptr2
|
||||
%tmp10 = select i1 %tmp6, i32 %tmp7, i32 %tmp9
|
||||
%tmp11 = srem i32 0, %tmp10
|
||||
%tmp12 = trunc i32 %tmp11 to i16
|
||||
br label %bb1
|
||||
}
|
||||
|
||||
; Use a particular instruction pattern in order to lower to the post-RA pseudo
|
||||
; used to lower SETB into an SBB pattern in order to make sure that kind of
|
||||
; usage of a copied EFLAGS continues to work.
|
||||
define void @PR37431(i32* %arg1, i8* %arg2, i8* %arg3) {
|
||||
; X32-LABEL: PR37431:
|
||||
; X32: # %bb.0: # %entry
|
||||
; X32-NEXT: pushl %esi
|
||||
; X32-NEXT: .cfi_def_cfa_offset 8
|
||||
; X32-NEXT: .cfi_offset %esi, -8
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-NEXT: movl (%eax), %eax
|
||||
; X32-NEXT: movl %eax, %ecx
|
||||
; X32-NEXT: sarl $31, %ecx
|
||||
; X32-NEXT: cmpl %eax, %eax
|
||||
; X32-NEXT: sbbl %ecx, %eax
|
||||
; X32-NEXT: setb %al
|
||||
; X32-NEXT: sbbb %cl, %cl
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; X32-NEXT: movb %cl, (%edx)
|
||||
; X32-NEXT: movzbl %al, %eax
|
||||
; X32-NEXT: xorl %ecx, %ecx
|
||||
; X32-NEXT: subl %eax, %ecx
|
||||
; X32-NEXT: xorl %eax, %eax
|
||||
; X32-NEXT: xorl %edx, %edx
|
||||
; X32-NEXT: idivl %ecx
|
||||
; X32-NEXT: movb %dl, (%esi)
|
||||
; X32-NEXT: popl %esi
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: PR37431:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: movq %rdx, %rcx
|
||||
; X64-NEXT: movslq (%rdi), %rax
|
||||
; X64-NEXT: cmpq %rax, %rax
|
||||
; X64-NEXT: sbbb %dl, %dl
|
||||
; X64-NEXT: cmpq %rax, %rax
|
||||
; X64-NEXT: movb %dl, (%rsi)
|
||||
; X64-NEXT: sbbl %esi, %esi
|
||||
; X64-NEXT: xorl %eax, %eax
|
||||
; X64-NEXT: xorl %edx, %edx
|
||||
; X64-NEXT: idivl %esi
|
||||
; X64-NEXT: movb %dl, (%rcx)
|
||||
; X64-NEXT: retq
|
||||
entry:
|
||||
%tmp = load i32, i32* %arg1
|
||||
%tmp1 = sext i32 %tmp to i64
|
||||
%tmp2 = icmp ugt i64 %tmp1, undef
|
||||
%tmp3 = zext i1 %tmp2 to i8
|
||||
%tmp4 = sub i8 0, %tmp3
|
||||
store i8 %tmp4, i8* %arg2
|
||||
%tmp5 = sext i8 %tmp4 to i32
|
||||
%tmp6 = srem i32 0, %tmp5
|
||||
%tmp7 = trunc i32 %tmp6 to i8
|
||||
store i8 %tmp7, i8* %arg3
|
||||
ret void
|
||||
}
|
||||
|
||||
24
external/llvm/test/CodeGen/X86/domain-reassignment-implicit-def.ll
vendored
Normal file
24
external/llvm/test/CodeGen/X86/domain-reassignment-implicit-def.ll
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
; RUN: llc -mcpu=skylake-avx512 -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s
|
||||
|
||||
; Check that the X86 Domain Reassignment pass doesn't drop IMPLICIT_DEF nodes,
|
||||
; which would later cause crashes (e.g. in LiveVariables) - see PR37430
|
||||
define void @domain_reassignment_implicit_def(i1 %cond, i8 *%mem, float %arg) {
|
||||
; CHECK: vxorps %xmm1, %xmm1, %xmm1
|
||||
; CHECK: vcmpneqss %xmm1, %xmm0, %k0
|
||||
; CHECK: kmovb %k0, (%rsi)
|
||||
top:
|
||||
br i1 %cond, label %L19, label %L15
|
||||
|
||||
L15: ; preds = %top
|
||||
%tmp47 = fcmp une float 0.000000e+00, %arg
|
||||
%tmp48 = zext i1 %tmp47 to i8
|
||||
br label %L21
|
||||
|
||||
L19: ; preds = %top
|
||||
br label %L21
|
||||
|
||||
L21: ; preds = %L19, %L15
|
||||
%.sroa.0.0 = phi i8 [ undef, %L19 ], [ %tmp48, %L15 ]
|
||||
store i8 %.sroa.0.0, i8* %mem, align 1
|
||||
ret void
|
||||
}
|
||||
37
external/llvm/test/CodeGen/X86/domain-reassignment-test.ll
vendored
Normal file
37
external/llvm/test/CodeGen/X86/domain-reassignment-test.ll
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
; RUN: llc -mcpu=skylake-avx512 -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s
|
||||
; RUN: llc -mcpu=skylake-avx512 -mtriple=x86_64-unknown-linux-gnu %s -o - | llvm-mc -triple=x86_64-unknown-linux-gnu -mcpu=skylake-avx512
|
||||
|
||||
; Check that the X86 domain reassignment pass doesn't introduce an illegal
|
||||
; test instruction. See PR37396
|
||||
define void @japi1_foo2_34617() {
|
||||
pass2:
|
||||
br label %if5
|
||||
|
||||
L174:
|
||||
%tmp = icmp sgt <2 x i64> undef, zeroinitializer
|
||||
%tmp1 = icmp sle <2 x i64> undef, undef
|
||||
%tmp2 = and <2 x i1> %tmp, %tmp1
|
||||
%tmp3 = extractelement <2 x i1> %tmp2, i32 0
|
||||
%tmp4 = extractelement <2 x i1> %tmp2, i32 1
|
||||
%tmp106 = and i1 %tmp4, %tmp3
|
||||
%tmp107 = zext i1 %tmp106 to i8
|
||||
%tmp108 = and i8 %tmp122, %tmp107
|
||||
%tmp109 = icmp eq i8 %tmp108, 0
|
||||
; CHECK-NOT: testb {{%k[0-7]}}
|
||||
br i1 %tmp109, label %L188, label %L190
|
||||
|
||||
if5:
|
||||
%b.055 = phi i8 [ 1, %pass2 ], [ %tmp122, %if5 ]
|
||||
%tmp118 = icmp sgt i64 undef, 0
|
||||
%tmp119 = icmp sle i64 undef, undef
|
||||
%tmp120 = and i1 %tmp118, %tmp119
|
||||
%tmp121 = zext i1 %tmp120 to i8
|
||||
%tmp122 = and i8 %b.055, %tmp121
|
||||
br i1 undef, label %L174, label %if5
|
||||
|
||||
L188:
|
||||
unreachable
|
||||
|
||||
L190:
|
||||
ret void
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
# RUN: llc -run-pass postrapseudos -mtriple=i386-apple-macosx -o - %s | FileCheck %s
|
||||
|
||||
# Verify that we correctly save and restore eax when copying eflags,
|
||||
# even when only a smaller alias of eax is used. We used to check only
|
||||
# eax and not its aliases.
|
||||
# PR27624.
|
||||
|
||||
--- |
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
br label %false
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
---
|
||||
name: foo
|
||||
tracksRegLiveness: true
|
||||
liveins:
|
||||
- { reg: '%edi' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %edi
|
||||
NOOP implicit-def %al
|
||||
|
||||
; The bug was triggered only when LivePhysReg is used, which
|
||||
; happens only when the heuristic for the liveness computation
|
||||
; failed. The liveness computation heuristic looks at 10 instructions
|
||||
; before and after the copy. Make sure we do not reach the definition of
|
||||
; AL in 10 instructions, otherwise the heuristic will see that it is live.
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
NOOP
|
||||
; Save AL.
|
||||
; CHECK: PUSH32r killed %eax
|
||||
|
||||
; Copy edi into EFLAGS
|
||||
; CHECK-NEXT: %eax = MOV32rr %edi
|
||||
; CHECK-NEXT: %al = ADD8ri %al, 127, implicit-def %eflags
|
||||
; CHECK-NEXT: SAHF implicit-def %eflags, implicit %ah
|
||||
%eflags = COPY %edi
|
||||
|
||||
; Restore AL.
|
||||
; CHECK-NEXT: %eax = POP32r
|
||||
bb.1.false:
|
||||
liveins: %al
|
||||
NOOP implicit %al
|
||||
RETQ
|
||||
|
||||
...
|
||||
@@ -381,3 +381,15 @@ define i64 @ashr_imm4_i64(i64 %a) {
|
||||
%c = ashr i64 %a, 4
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
; Make sure we don't crash on out of bounds i8 shifts.
|
||||
define i8 @PR36731(i8 %a) {
|
||||
; CHECK-LABEL: PR36731:
|
||||
; CHECK: ## %bb.0:
|
||||
; CHECK-NEXT: movb $255, %cl
|
||||
; CHECK-NEXT: shlb %cl, %dil
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%b = shl i8 %a, -1
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
555
external/llvm/test/CodeGen/X86/flags-copy-lowering.mir
vendored
Normal file
555
external/llvm/test/CodeGen/X86/flags-copy-lowering.mir
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
target triple = "x86_64-unknown-unknown"
|
||||
declare void @bar1()
|
||||
define preserve_allcc void @foo()#0 {
|
||||
; CHECK: foo Clobbered Registers: %cs %ds %eflags %eip %eiz %es %fpsw %fs %gs %ip %rip %riz %ss %ssp %bnd0 %bnd1 %bnd2 %bnd3 %cr0 %cr1 %cr2 %cr3 %cr4 %cr5 %cr6 %cr7 %cr8 %cr9 %cr10 %cr11 %cr12 %cr13 %cr14 %cr15 %dr0 %dr1 %dr2 %dr3 %dr4 %dr5 %dr6 %dr7 %dr8 %dr9 %dr10 %dr11 %dr12 %dr13 %dr14 %dr15 %fp0 %fp1 %fp2 %fp3 %fp4 %fp5 %fp6 %fp7 %k0 %k1 %k2 %k3 %k4 %k5 %k6 %k7 %mm0 %mm1 %mm2 %mm3 %mm4 %mm5 %mm6 %mm7 %r11 %st0 %st1 %st2 %st3 %st4 %st5 %st6 %st7 %xmm16 %xmm17 %xmm18 %xmm19 %xmm20 %xmm21 %xmm22 %xmm23 %xmm24 %xmm25 %xmm26 %xmm27 %xmm28 %xmm29 %xmm30 %xmm31 %ymm0 %ymm1 %ymm2 %ymm3 %ymm4 %ymm5 %ymm6 %ymm7 %ymm8 %ymm9 %ymm10 %ymm11 %ymm12 %ymm13 %ymm14 %ymm15 %ymm16 %ymm17 %ymm18 %ymm19 %ymm20 %ymm21 %ymm22 %ymm23 %ymm24 %ymm25 %ymm26 %ymm27 %ymm28 %ymm29 %ymm30 %ymm31 %zmm0 %zmm1 %zmm2 %zmm3 %zmm4 %zmm5 %zmm6 %zmm7 %zmm8 %zmm9 %zmm10 %zmm11 %zmm12 %zmm13 %zmm14 %zmm15 %zmm16 %zmm17 %zmm18 %zmm19 %zmm20 %zmm21 %zmm22 %zmm23 %zmm24 %zmm25 %zmm26 %zmm27 %zmm28 %zmm29 %zmm30 %zmm31 %r11b %r11d %r11w
|
||||
; CHECK: foo Clobbered Registers: %cs %df %ds %eflags %eip %eiz %es %fpsw %fs %gs %ip %rip %riz %ss %ssp %bnd0 %bnd1 %bnd2 %bnd3 %cr0 %cr1 %cr2 %cr3 %cr4 %cr5 %cr6 %cr7 %cr8 %cr9 %cr10 %cr11 %cr12 %cr13 %cr14 %cr15 %dr0 %dr1 %dr2 %dr3 %dr4 %dr5 %dr6 %dr7 %dr8 %dr9 %dr10 %dr11 %dr12 %dr13 %dr14 %dr15 %fp0 %fp1 %fp2 %fp3 %fp4 %fp5 %fp6 %fp7 %k0 %k1 %k2 %k3 %k4 %k5 %k6 %k7 %mm0 %mm1 %mm2 %mm3 %mm4 %mm5 %mm6 %mm7 %r11 %st0 %st1 %st2 %st3 %st4 %st5 %st6 %st7 %xmm16 %xmm17 %xmm18 %xmm19 %xmm20 %xmm21 %xmm22 %xmm23 %xmm24 %xmm25 %xmm26 %xmm27 %xmm28 %xmm29 %xmm30 %xmm31 %ymm0 %ymm1 %ymm2 %ymm3 %ymm4 %ymm5 %ymm6 %ymm7 %ymm8 %ymm9 %ymm10 %ymm11 %ymm12 %ymm13 %ymm14 %ymm15 %ymm16 %ymm17 %ymm18 %ymm19 %ymm20 %ymm21 %ymm22 %ymm23 %ymm24 %ymm25 %ymm26 %ymm27 %ymm28 %ymm29 %ymm30 %ymm31 %zmm0 %zmm1 %zmm2 %zmm3 %zmm4 %zmm5 %zmm6 %zmm7 %zmm8 %zmm9 %zmm10 %zmm11 %zmm12 %zmm13 %zmm14 %zmm15 %zmm16 %zmm17 %zmm18 %zmm19 %zmm20 %zmm21 %zmm22 %zmm23 %zmm24 %zmm25 %zmm26 %zmm27 %zmm28 %zmm29 %zmm30 %zmm31 %r11b %r11d %r11w
|
||||
call void @bar1()
|
||||
call void @bar2()
|
||||
ret void
|
||||
|
||||
@@ -1 +1 @@
|
||||
9980042a4ccc8fbd2d076d697f931340813ec909
|
||||
16fb112efadb2d79b4ca251491aefd844d079edf
|
||||
@@ -1,13 +1,10 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=i386-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64
|
||||
|
||||
; TODO: Reenable verify-machineinstrs once the if (!AXDead) // FIXME in
|
||||
; X86InstrInfo::copyPhysReg() is resolved.
|
||||
; RUN: llc -mtriple=i386-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32
|
||||
; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64
|
||||
|
||||
; The peephole optimizer can elide some physical register copies such as
|
||||
; EFLAGS. Make sure the flags are used directly, instead of needlessly using
|
||||
; lahf, when possible.
|
||||
; saving and restoring specific conditions.
|
||||
|
||||
@L = external global i32
|
||||
@M = external global i8
|
||||
@@ -209,29 +206,22 @@ exit2:
|
||||
define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) nounwind {
|
||||
; CHECK32-LABEL: test_intervening_call:
|
||||
; CHECK32: # %bb.0: # %entry
|
||||
; CHECK32-NEXT: pushl %ebp
|
||||
; CHECK32-NEXT: movl %esp, %ebp
|
||||
; CHECK32-NEXT: pushl %ebx
|
||||
; CHECK32-NEXT: pushl %esi
|
||||
; CHECK32-NEXT: movl 12(%ebp), %eax
|
||||
; CHECK32-NEXT: movl 16(%ebp), %edx
|
||||
; CHECK32-NEXT: movl 20(%ebp), %ebx
|
||||
; CHECK32-NEXT: movl 24(%ebp), %ecx
|
||||
; CHECK32-NEXT: movl 8(%ebp), %esi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%esi)
|
||||
; CHECK32-NEXT: pushl %eax
|
||||
; CHECK32-NEXT: seto %al
|
||||
; CHECK32-NEXT: lahf
|
||||
; CHECK32-NEXT: movl %eax, %esi
|
||||
; CHECK32-NEXT: popl %eax
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%esi)
|
||||
; CHECK32-NEXT: setne %bl
|
||||
; CHECK32-NEXT: subl $8, %esp
|
||||
; CHECK32-NEXT: pushl %edx
|
||||
; CHECK32-NEXT: pushl %eax
|
||||
; CHECK32-NEXT: calll bar
|
||||
; CHECK32-NEXT: addl $16, %esp
|
||||
; CHECK32-NEXT: movl %esi, %eax
|
||||
; CHECK32-NEXT: addb $127, %al
|
||||
; CHECK32-NEXT: sahf
|
||||
; CHECK32-NEXT: testb %bl, %bl
|
||||
; CHECK32-NEXT: jne .LBB4_3
|
||||
; CHECK32-NEXT: # %bb.1: # %t
|
||||
; CHECK32-NEXT: movl $42, %eax
|
||||
@@ -240,39 +230,28 @@ define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) nounwind {
|
||||
; CHECK32-NEXT: xorl %eax, %eax
|
||||
; CHECK32-NEXT: .LBB4_2: # %t
|
||||
; CHECK32-NEXT: xorl %edx, %edx
|
||||
; CHECK32-NEXT: addl $4, %esp
|
||||
; CHECK32-NEXT: popl %esi
|
||||
; CHECK32-NEXT: popl %ebx
|
||||
; CHECK32-NEXT: popl %ebp
|
||||
; CHECK32-NEXT: retl
|
||||
;
|
||||
; CHECK64-LABEL: test_intervening_call:
|
||||
; CHECK64: # %bb.0: # %entry
|
||||
; CHECK64-NEXT: pushq %rbp
|
||||
; CHECK64-NEXT: movq %rsp, %rbp
|
||||
; CHECK64-NEXT: pushq %rbx
|
||||
; CHECK64-NEXT: pushq %rax
|
||||
; CHECK64-NEXT: movq %rsi, %rax
|
||||
; CHECK64-NEXT: lock cmpxchgq %rdx, (%rdi)
|
||||
; CHECK64-NEXT: pushq %rax
|
||||
; CHECK64-NEXT: seto %al
|
||||
; CHECK64-NEXT: lahf
|
||||
; CHECK64-NEXT: movq %rax, %rbx
|
||||
; CHECK64-NEXT: popq %rax
|
||||
; CHECK64-NEXT: setne %bl
|
||||
; CHECK64-NEXT: movq %rax, %rdi
|
||||
; CHECK64-NEXT: callq bar
|
||||
; CHECK64-NEXT: movq %rbx, %rax
|
||||
; CHECK64-NEXT: addb $127, %al
|
||||
; CHECK64-NEXT: sahf
|
||||
; CHECK64-NEXT: jne .LBB4_3
|
||||
; CHECK64-NEXT: testb %bl, %bl
|
||||
; CHECK64-NEXT: jne .LBB4_2
|
||||
; CHECK64-NEXT: # %bb.1: # %t
|
||||
; CHECK64-NEXT: movl $42, %eax
|
||||
; CHECK64-NEXT: jmp .LBB4_2
|
||||
; CHECK64-NEXT: .LBB4_3: # %f
|
||||
; CHECK64-NEXT: xorl %eax, %eax
|
||||
; CHECK64-NEXT: .LBB4_2: # %t
|
||||
; CHECK64-NEXT: addq $8, %rsp
|
||||
; CHECK64-NEXT: popq %rbx
|
||||
; CHECK64-NEXT: popq %rbp
|
||||
; CHECK64-NEXT: retq
|
||||
; CHECK64-NEXT: .LBB4_2: # %f
|
||||
; CHECK64-NEXT: xorl %eax, %eax
|
||||
; CHECK64-NEXT: popq %rbx
|
||||
; CHECK64-NEXT: retq
|
||||
entry:
|
||||
; cmpxchg sets EFLAGS, call clobbers it, then br uses EFLAGS.
|
||||
@@ -293,32 +272,27 @@ define i64 @test_two_live_flags(i64* %foo0, i64 %bar0, i64 %baz0, i64* %foo1, i6
|
||||
; CHECK32-LABEL: test_two_live_flags:
|
||||
; CHECK32: # %bb.0: # %entry
|
||||
; CHECK32-NEXT: pushl %ebp
|
||||
; CHECK32-NEXT: movl %esp, %ebp
|
||||
; CHECK32-NEXT: pushl %ebx
|
||||
; CHECK32-NEXT: pushl %edi
|
||||
; CHECK32-NEXT: pushl %esi
|
||||
; CHECK32-NEXT: movl 44(%ebp), %edi
|
||||
; CHECK32-NEXT: movl 12(%ebp), %eax
|
||||
; CHECK32-NEXT: movl 16(%ebp), %edx
|
||||
; CHECK32-NEXT: movl 20(%ebp), %ebx
|
||||
; CHECK32-NEXT: movl 24(%ebp), %ecx
|
||||
; CHECK32-NEXT: movl 8(%ebp), %esi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%esi)
|
||||
; CHECK32-NEXT: seto %al
|
||||
; CHECK32-NEXT: lahf
|
||||
; CHECK32-NEXT: movl %eax, %esi
|
||||
; CHECK32-NEXT: movl 32(%ebp), %eax
|
||||
; CHECK32-NEXT: movl 36(%ebp), %edx
|
||||
; CHECK32-NEXT: movl %edi, %ecx
|
||||
; CHECK32-NEXT: movl 40(%ebp), %ebx
|
||||
; CHECK32-NEXT: movl 28(%ebp), %edi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%edi)
|
||||
; CHECK32-NEXT: sete %al
|
||||
; CHECK32-NEXT: pushl %eax
|
||||
; CHECK32-NEXT: movl %esi, %eax
|
||||
; CHECK32-NEXT: addb $127, %al
|
||||
; CHECK32-NEXT: sahf
|
||||
; CHECK32-NEXT: popl %eax
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %edi
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ebp
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%esi)
|
||||
; CHECK32-NEXT: setne {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; CHECK32-NEXT: movl %edi, %edx
|
||||
; CHECK32-NEXT: movl %ebp, %ecx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %ebx
|
||||
; CHECK32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
||||
; CHECK32-NEXT: lock cmpxchg8b (%esi)
|
||||
; CHECK32-NEXT: sete %al
|
||||
; CHECK32-NEXT: cmpb $0, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Reload
|
||||
; CHECK32-NEXT: jne .LBB5_4
|
||||
; CHECK32-NEXT: # %bb.1: # %entry
|
||||
; CHECK32-NEXT: testb %al, %al
|
||||
@@ -330,6 +304,7 @@ define i64 @test_two_live_flags(i64* %foo0, i64 %bar0, i64 %baz0, i64* %foo1, i6
|
||||
; CHECK32-NEXT: xorl %eax, %eax
|
||||
; CHECK32-NEXT: .LBB5_3: # %t
|
||||
; CHECK32-NEXT: xorl %edx, %edx
|
||||
; CHECK32-NEXT: addl $4, %esp
|
||||
; CHECK32-NEXT: popl %esi
|
||||
; CHECK32-NEXT: popl %edi
|
||||
; CHECK32-NEXT: popl %ebx
|
||||
@@ -338,32 +313,22 @@ define i64 @test_two_live_flags(i64* %foo0, i64 %bar0, i64 %baz0, i64* %foo1, i6
|
||||
;
|
||||
; CHECK64-LABEL: test_two_live_flags:
|
||||
; CHECK64: # %bb.0: # %entry
|
||||
; CHECK64-NEXT: pushq %rbp
|
||||
; CHECK64-NEXT: movq %rsp, %rbp
|
||||
; CHECK64-NEXT: movq %rsi, %rax
|
||||
; CHECK64-NEXT: lock cmpxchgq %rdx, (%rdi)
|
||||
; CHECK64-NEXT: seto %al
|
||||
; CHECK64-NEXT: lahf
|
||||
; CHECK64-NEXT: movq %rax, %rdx
|
||||
; CHECK64-NEXT: setne %dl
|
||||
; CHECK64-NEXT: movq %r8, %rax
|
||||
; CHECK64-NEXT: lock cmpxchgq %r9, (%rcx)
|
||||
; CHECK64-NEXT: sete %al
|
||||
; CHECK64-NEXT: pushq %rax
|
||||
; CHECK64-NEXT: movq %rdx, %rax
|
||||
; CHECK64-NEXT: addb $127, %al
|
||||
; CHECK64-NEXT: sahf
|
||||
; CHECK64-NEXT: popq %rax
|
||||
; CHECK64-NEXT: testb %dl, %dl
|
||||
; CHECK64-NEXT: jne .LBB5_3
|
||||
; CHECK64-NEXT: # %bb.1: # %entry
|
||||
; CHECK64-NEXT: testb %al, %al
|
||||
; CHECK64-NEXT: je .LBB5_3
|
||||
; CHECK64-NEXT: # %bb.2: # %t
|
||||
; CHECK64-NEXT: movl $42, %eax
|
||||
; CHECK64-NEXT: popq %rbp
|
||||
; CHECK64-NEXT: retq
|
||||
; CHECK64-NEXT: .LBB5_3: # %f
|
||||
; CHECK64-NEXT: xorl %eax, %eax
|
||||
; CHECK64-NEXT: popq %rbp
|
||||
; CHECK64-NEXT: retq
|
||||
entry:
|
||||
%cx0 = cmpxchg i64* %foo0, i64 %bar0, i64 %baz0 seq_cst seq_cst
|
||||
|
||||
12
external/llvm/test/CodeGen/X86/pr37264.ll
vendored
Normal file
12
external/llvm/test/CodeGen/X86/pr37264.ll
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
; RUN: llc < %s -mtriple=x86_64--
|
||||
|
||||
define void @a() local_unnamed_addr #0 {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @b() local_unnamed_addr #1 {
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+avx,+avx2,+avx512bw,+avx512f,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
|
||||
attributes #1 = { "target-features"="+avx,+avx2,+avx512f,+avx512vl,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
|
||||
334
external/llvm/test/CodeGen/X86/win64_frame.ll
vendored
334
external/llvm/test/CodeGen/X86/win64_frame.ll
vendored
@@ -1,43 +1,85 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=PUSHF
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=SAHF
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=ALL --check-prefix=PUSHF
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=ALL --check-prefix=SAHF
|
||||
|
||||
define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK: movl 48(%rbp), %eax
|
||||
; ALL-LABEL: f1:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: movq %rsp, %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 0
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: movl 48(%rbp), %eax
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
ret i32 %p5
|
||||
}
|
||||
|
||||
define void @f2(i32 %p, ...) "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f2:
|
||||
; CHECK: .seh_stackalloc 8
|
||||
; CHECK: movq %rsp, %rbp
|
||||
; CHECK: .seh_setframe 5, 0
|
||||
; CHECK: movq %rdx, 32(%rbp)
|
||||
; CHECK: leaq 32(%rbp), %rax
|
||||
; ALL-LABEL: f2:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: pushq %rax
|
||||
; ALL-NEXT: .seh_stackalloc 8
|
||||
; ALL-NEXT: movq %rsp, %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 0
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: movq %r9, 48(%rbp)
|
||||
; ALL-NEXT: movq %r8, 40(%rbp)
|
||||
; ALL-NEXT: movq %rdx, 32(%rbp)
|
||||
; ALL-NEXT: leaq 32(%rbp), %rax
|
||||
; ALL-NEXT: movq %rax, (%rbp)
|
||||
; ALL-NEXT: addq $8, %rsp
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%ap = alloca i8, align 8
|
||||
call void @llvm.va_start(i8* %ap)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i8* @f3() "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f3:
|
||||
; CHECK: movq %rsp, %rbp
|
||||
; CHECK: .seh_setframe 5, 0
|
||||
; CHECK: movq 8(%rbp), %rax
|
||||
; ALL-LABEL: f3:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: movq %rsp, %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 0
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: movq 8(%rbp), %rax
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%ra = call i8* @llvm.returnaddress(i32 0)
|
||||
ret i8* %ra
|
||||
}
|
||||
|
||||
define i8* @f4() "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f4:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: .seh_pushreg 5
|
||||
; CHECK: subq $304, %rsp
|
||||
; CHECK: .seh_stackalloc 304
|
||||
; CHECK: leaq 128(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 128
|
||||
; CHECK: .seh_endprologue
|
||||
; CHECK: movq 184(%rbp), %rax
|
||||
; ALL-LABEL: f4:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: subq $304, %rsp # imm = 0x130
|
||||
; ALL-NEXT: .seh_stackalloc 304
|
||||
; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 128
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: movq 184(%rbp), %rax
|
||||
; ALL-NEXT: addq $304, %rsp # imm = 0x130
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
alloca [300 x i8]
|
||||
%ra = call i8* @llvm.returnaddress(i32 0)
|
||||
ret i8* %ra
|
||||
@@ -46,13 +88,24 @@ define i8* @f4() "no-frame-pointer-elim"="true" {
|
||||
declare void @external(i8*)
|
||||
|
||||
define void @f5() "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f5:
|
||||
; CHECK: subq $336, %rsp
|
||||
; CHECK: .seh_stackalloc 336
|
||||
; CHECK: leaq 128(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 128
|
||||
; CHECK: leaq -92(%rbp), %rcx
|
||||
; CHECK: callq external
|
||||
; ALL-LABEL: f5:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: subq $336, %rsp # imm = 0x150
|
||||
; ALL-NEXT: .seh_stackalloc 336
|
||||
; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 128
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: leaq -92(%rbp), %rcx
|
||||
; ALL-NEXT: callq external
|
||||
; ALL-NEXT: nop
|
||||
; ALL-NEXT: addq $336, %rsp # imm = 0x150
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%a = alloca [300 x i8]
|
||||
%gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
|
||||
call void @external(i8* %gep)
|
||||
@@ -60,13 +113,24 @@ define void @f5() "no-frame-pointer-elim"="true" {
|
||||
}
|
||||
|
||||
define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f6:
|
||||
; CHECK: subq $336, %rsp
|
||||
; CHECK: .seh_stackalloc 336
|
||||
; CHECK: leaq 128(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 128
|
||||
; CHECK: leaq -92(%rbp), %rcx
|
||||
; CHECK: callq external
|
||||
; ALL-LABEL: f6:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: subq $336, %rsp # imm = 0x150
|
||||
; ALL-NEXT: .seh_stackalloc 336
|
||||
; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 128
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: leaq -92(%rbp), %rcx
|
||||
; ALL-NEXT: callq external
|
||||
; ALL-NEXT: nop
|
||||
; ALL-NEXT: addq $336, %rsp # imm = 0x150
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%a = alloca [300 x i8]
|
||||
%gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
|
||||
call void @external(i8* %gep)
|
||||
@@ -74,130 +138,147 @@ define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" {
|
||||
}
|
||||
|
||||
define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f7:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: .seh_pushreg 5
|
||||
; CHECK: subq $304, %rsp
|
||||
; CHECK: .seh_stackalloc 304
|
||||
; CHECK: leaq 128(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 128
|
||||
; CHECK: andq $-64, %rsp
|
||||
; CHECK: movl 224(%rbp), %eax
|
||||
; CHECK: leaq 176(%rbp), %rsp
|
||||
; ALL-LABEL: f7:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: subq $304, %rsp # imm = 0x130
|
||||
; ALL-NEXT: .seh_stackalloc 304
|
||||
; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 128
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: andq $-64, %rsp
|
||||
; ALL-NEXT: movl 224(%rbp), %eax
|
||||
; ALL-NEXT: leaq 176(%rbp), %rsp
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
alloca [300 x i8], align 64
|
||||
ret i32 %e
|
||||
}
|
||||
|
||||
define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f8:
|
||||
; CHECK: subq $352, %rsp
|
||||
; CHECK: .seh_stackalloc 352
|
||||
; CHECK: leaq 128(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 128
|
||||
|
||||
; ALL-LABEL: f8:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: pushq %rsi
|
||||
; ALL-NEXT: .seh_pushreg 6
|
||||
; ALL-NEXT: pushq %rbx
|
||||
; ALL-NEXT: .seh_pushreg 3
|
||||
; ALL-NEXT: subq $352, %rsp # imm = 0x160
|
||||
; ALL-NEXT: .seh_stackalloc 352
|
||||
; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 128
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: andq $-64, %rsp
|
||||
; ALL-NEXT: movq %rsp, %rbx
|
||||
; ALL-NEXT: movl 288(%rbp), %esi
|
||||
; ALL-NEXT: movl %ecx, %eax
|
||||
; ALL-NEXT: leaq 15(,%rax,4), %rcx
|
||||
; ALL-NEXT: movabsq $34359738352, %rax # imm = 0x7FFFFFFF0
|
||||
; ALL-NEXT: andq %rcx, %rax
|
||||
; ALL-NEXT: callq __chkstk
|
||||
; ALL-NEXT: subq %rax, %rsp
|
||||
; ALL-NEXT: subq $32, %rsp
|
||||
; ALL-NEXT: movq %rbx, %rcx
|
||||
; ALL-NEXT: callq external
|
||||
; ALL-NEXT: addq $32, %rsp
|
||||
; ALL-NEXT: movl %esi, %eax
|
||||
; ALL-NEXT: leaq 224(%rbp), %rsp
|
||||
; ALL-NEXT: popq %rbx
|
||||
; ALL-NEXT: popq %rsi
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%alloca = alloca [300 x i8], align 64
|
||||
; CHECK: andq $-64, %rsp
|
||||
; CHECK: movq %rsp, %rbx
|
||||
|
||||
alloca i32, i32 %a
|
||||
; CHECK: movl %ecx, %eax
|
||||
; CHECK: leaq 15(,%rax,4), %rcx
|
||||
; CHECK: movabsq $34359738352, %rax
|
||||
; CHECK: andq %rcx, %rax
|
||||
; CHECK: callq __chkstk
|
||||
; CHECK: subq %rax, %rsp
|
||||
|
||||
%gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0
|
||||
call void @external(i8* %gep)
|
||||
; CHECK: subq $32, %rsp
|
||||
; CHECK: movq %rbx, %rcx
|
||||
; CHECK: callq external
|
||||
; CHECK: addq $32, %rsp
|
||||
|
||||
ret i32 %e
|
||||
; CHECK: movl %esi, %eax
|
||||
; CHECK: leaq 224(%rbp), %rsp
|
||||
}
|
||||
|
||||
define i64 @f9() {
|
||||
; ALL-LABEL: f9:
|
||||
; ALL: # %bb.0: # %entry
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: movq %rsp, %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 0
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: pushfq
|
||||
; ALL-NEXT: popq %rax
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
entry:
|
||||
; CHECK-LABEL: f9:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: .seh_pushreg 5
|
||||
; CHECK-NEXT: movq %rsp, %rbp
|
||||
; CHECK: .seh_setframe 5, 0
|
||||
; CHECK: .seh_endprologue
|
||||
|
||||
%call = call i64 @llvm.x86.flags.read.u64()
|
||||
; CHECK-NEXT: pushfq
|
||||
; CHECK-NEXT: popq %rax
|
||||
|
||||
ret i64 %call
|
||||
; CHECK-NEXT: popq %rbp
|
||||
; CHECK-NEXT: retq
|
||||
}
|
||||
|
||||
declare i64 @dummy()
|
||||
|
||||
define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
|
||||
; CHECK-LABEL: f10:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: .seh_pushreg 5
|
||||
; CHECK: pushq %rsi
|
||||
; CHECK: .seh_pushreg 6
|
||||
; CHECK: pushq %rdi
|
||||
; CHECK: .seh_pushreg 7
|
||||
; CHECK: subq $32, %rsp
|
||||
; CHECK: .seh_stackalloc 32
|
||||
; CHECK: leaq 32(%rsp), %rbp
|
||||
; CHECK: .seh_setframe 5, 32
|
||||
; CHECK: .seh_endprologue
|
||||
|
||||
; ALL-LABEL: f10:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rsi
|
||||
; ALL-NEXT: .seh_pushreg 6
|
||||
; ALL-NEXT: pushq %rbx
|
||||
; ALL-NEXT: .seh_pushreg 3
|
||||
; ALL-NEXT: subq $40, %rsp
|
||||
; ALL-NEXT: .seh_stackalloc 40
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: movq %rdx, %rsi
|
||||
; ALL-NEXT: movq %rsi, %rax
|
||||
; ALL-NEXT: lock cmpxchgq %r8, (%rcx)
|
||||
; ALL-NEXT: sete %bl
|
||||
; ALL-NEXT: callq dummy
|
||||
; ALL-NEXT: testb %bl, %bl
|
||||
; ALL-NEXT: cmoveq %rsi, %rax
|
||||
; ALL-NEXT: addq $40, %rsp
|
||||
; ALL-NEXT: popq %rbx
|
||||
; ALL-NEXT: popq %rsi
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
|
||||
; PUSHF: lock cmpxchgq
|
||||
; PUSHF-NEXT: pushfq
|
||||
; PUSHF-NEXT: popq %[[REG:.*]]
|
||||
; SAHF: lock cmpxchgq
|
||||
; SAHF-NEXT: seto %al
|
||||
; SAHF-NEXT: lahf
|
||||
|
||||
%v = extractvalue { i64, i1 } %cx, 0
|
||||
%p = extractvalue { i64, i1 } %cx, 1
|
||||
|
||||
%call = call i64 @dummy()
|
||||
; PUSHF: callq dummy
|
||||
; PUSHF-NEXT: pushq %[[REG]]
|
||||
; PUSHF-NEXT: popfq
|
||||
; SAHF: callq dummy
|
||||
; SAHF-NEXT: pushq
|
||||
; SAHF: addb $127, %al
|
||||
; SAHF-NEXT: sahf
|
||||
; SAHF-NEXT: popq
|
||||
|
||||
%sel = select i1 %p, i64 %call, i64 %bar
|
||||
; CHECK-NEXT: cmovneq
|
||||
|
||||
ret i64 %sel
|
||||
; CHECK-NEXT: addq $32, %rsp
|
||||
; CHECK-NEXT: popq %rdi
|
||||
; CHECK-NEXT: popq %rsi
|
||||
; CHECK-NEXT: popq %rbp
|
||||
}
|
||||
|
||||
define i8* @f11() "no-frame-pointer-elim"="true" {
|
||||
; CHECK-LABEL: f11:
|
||||
; CHECK: pushq %rbp
|
||||
; CHECK: movq %rsp, %rbp
|
||||
; CHECK: .seh_setframe 5, 0
|
||||
; CHECK: leaq 8(%rbp), %rax
|
||||
; ALL-LABEL: f11:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: pushq %rbp
|
||||
; ALL-NEXT: .seh_pushreg 5
|
||||
; ALL-NEXT: movq %rsp, %rbp
|
||||
; ALL-NEXT: .seh_setframe 5, 0
|
||||
; ALL-NEXT: .seh_endprologue
|
||||
; ALL-NEXT: leaq 8(%rbp), %rax
|
||||
; ALL-NEXT: popq %rbp
|
||||
; ALL-NEXT: retq
|
||||
; ALL-NEXT: .seh_handlerdata
|
||||
; ALL-NEXT: .text
|
||||
; ALL-NEXT: .seh_endproc
|
||||
%aora = call i8* @llvm.addressofreturnaddress()
|
||||
ret i8* %aora
|
||||
}
|
||||
|
||||
define i8* @f12() {
|
||||
; CHECK-LABEL: f12:
|
||||
; CHECK-NOT: push
|
||||
; CHECK: movq %rsp, %rax
|
||||
; ALL-LABEL: f12:
|
||||
; ALL: # %bb.0:
|
||||
; ALL-NEXT: movq %rsp, %rax
|
||||
; ALL-NEXT: retq
|
||||
%aora = call i8* @llvm.addressofreturnaddress()
|
||||
ret i8* %aora
|
||||
}
|
||||
@@ -205,5 +286,4 @@ define i8* @f12() {
|
||||
declare i8* @llvm.returnaddress(i32) nounwind readnone
|
||||
declare i8* @llvm.addressofreturnaddress() nounwind readnone
|
||||
declare i64 @llvm.x86.flags.read.u64()
|
||||
|
||||
declare void @llvm.va_start(i8*) nounwind
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s | FileCheck %s
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i686-pc-windows-msvc18.0.0"
|
||||
|
||||
@@ -39,15 +39,12 @@ declare void @g(%struct.T*)
|
||||
; CHECK: leal 8(%esp), %esi
|
||||
|
||||
; CHECK: decl (%esp)
|
||||
; CHECK: seto %al
|
||||
; CHECK: lahf
|
||||
; CHECK: movl %eax, %edi
|
||||
; CHECK: setne %[[NE_REG:.*]]
|
||||
; CHECK: pushl %esi
|
||||
; CHECK: calll _g
|
||||
; CHECK: addl $4, %esp
|
||||
; CHECK: movl %edi, %eax
|
||||
; CHECK: addb $127, %al
|
||||
; CHECK: sahf
|
||||
; CHECK: testb %[[NE_REG]], %[[NE_REG]]
|
||||
; CHECK: jne
|
||||
|
||||
attributes #0 = { nounwind optsize }
|
||||
attributes #1 = { argmemonly nounwind }
|
||||
|
||||
Reference in New Issue
Block a user