Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopStrengthReduce / X86 / macro-fuse-cmp.ll
blobfeff010300c1e11821b687b7f5c54de5704af3fa
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: opt < %s -loop-reduce -mcpu=btver2  -S | FileCheck %s --check-prefix=JAG
3 ; RUN: opt < %s -loop-reduce -mcpu=bdver2  -S | FileCheck %s --check-prefix=BUL
4 ; RUN: opt < %s -loop-reduce -mcpu=haswell -S | FileCheck %s --check-prefix=HSW
6 ; RUN: llc < %s                     | FileCheck %s --check-prefix=BASE
7 ; RUN: llc < %s -mattr=macrofusion  | FileCheck %s --check-prefix=FUSE
8 ; RUN: llc < %s -mattr=branchfusion | FileCheck %s --check-prefix=FUSE
10 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11 target triple = "x86_64-unknown-unknown"
13 ; PR35681 - https://bugs.llvm.org/show_bug.cgi?id=35681
14 ; FIXME: If a CPU can macro-fuse a compare and branch, then we discount that
15 ; cost in LSR and avoid generating large offsets in each memory access.
16 ; This reduces code size and may improve decode throughput.
18 define void @maxArray(ptr noalias nocapture %x, ptr noalias nocapture readonly %y) {
19 ; JAG-LABEL: @maxArray(
20 ; JAG-NEXT:  entry:
21 ; JAG-NEXT:    br label [[VECTOR_BODY:%.*]]
22 ; JAG:       vector.body:
23 ; JAG-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[VECTOR_BODY]] ], [ -524288, [[ENTRY:%.*]] ]
24 ; JAG-NEXT:    [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[LSR_IV]]
25 ; JAG-NEXT:    [[SCEVGEP3:%.*]] = getelementptr i8, ptr [[SCEVGEP2]], i64 524288
26 ; JAG-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[LSR_IV]]
27 ; JAG-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 524288
28 ; JAG-NEXT:    [[XVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP3]], align 8
29 ; JAG-NEXT:    [[YVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP1]], align 8
30 ; JAG-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x double> [[YVAL]], [[XVAL]]
31 ; JAG-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x double> [[YVAL]], <2 x double> [[XVAL]]
32 ; JAG-NEXT:    store <2 x double> [[MAX]], ptr [[SCEVGEP3]], align 8
33 ; JAG-NEXT:    [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], 16
34 ; JAG-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
35 ; JAG-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
36 ; JAG:       exit:
37 ; JAG-NEXT:    ret void
39 ; BUL-LABEL: @maxArray(
40 ; BUL-NEXT:  entry:
41 ; BUL-NEXT:    br label [[VECTOR_BODY:%.*]]
42 ; BUL:       vector.body:
43 ; BUL-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
44 ; BUL-NEXT:    [[TMP0:%.*]] = shl nuw nsw i64 [[INDEX]], 3
45 ; BUL-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[TMP0]]
46 ; BUL-NEXT:    [[TMP1:%.*]] = shl nuw nsw i64 [[INDEX]], 3
47 ; BUL-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[TMP1]]
48 ; BUL-NEXT:    [[XVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP1]], align 8
49 ; BUL-NEXT:    [[YVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP]], align 8
50 ; BUL-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x double> [[YVAL]], [[XVAL]]
51 ; BUL-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x double> [[YVAL]], <2 x double> [[XVAL]]
52 ; BUL-NEXT:    store <2 x double> [[MAX]], ptr [[SCEVGEP1]], align 8
53 ; BUL-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 2
54 ; BUL-NEXT:    [[DONE:%.*]] = icmp eq i64 [[INDEX_NEXT]], 65536
55 ; BUL-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
56 ; BUL:       exit:
57 ; BUL-NEXT:    ret void
59 ; HSW-LABEL: @maxArray(
60 ; HSW-NEXT:  entry:
61 ; HSW-NEXT:    br label [[VECTOR_BODY:%.*]]
62 ; HSW:       vector.body:
63 ; HSW-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
64 ; HSW-NEXT:    [[TMP0:%.*]] = shl nuw nsw i64 [[INDEX]], 3
65 ; HSW-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[TMP0]]
66 ; HSW-NEXT:    [[TMP1:%.*]] = shl nuw nsw i64 [[INDEX]], 3
67 ; HSW-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[TMP1]]
68 ; HSW-NEXT:    [[XVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP1]], align 8
69 ; HSW-NEXT:    [[YVAL:%.*]] = load <2 x double>, ptr [[SCEVGEP]], align 8
70 ; HSW-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x double> [[YVAL]], [[XVAL]]
71 ; HSW-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x double> [[YVAL]], <2 x double> [[XVAL]]
72 ; HSW-NEXT:    store <2 x double> [[MAX]], ptr [[SCEVGEP1]], align 8
73 ; HSW-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 2
74 ; HSW-NEXT:    [[DONE:%.*]] = icmp eq i64 [[INDEX_NEXT]], 65536
75 ; HSW-NEXT:    br i1 [[DONE]], label [[EXIT:%.*]], label [[VECTOR_BODY]]
76 ; HSW:       exit:
77 ; HSW-NEXT:    ret void
79 ; BASE-LABEL: maxArray:
80 ; BASE:       # %bb.0: # %entry
81 ; BASE-NEXT:    movq $-524288, %rax # imm = 0xFFF80000
82 ; BASE-NEXT:    .p2align 4, 0x90
83 ; BASE-NEXT:  .LBB0_1: # %vector.body
84 ; BASE-NEXT:    # =>This Inner Loop Header: Depth=1
85 ; BASE-NEXT:    movupd 524288(%rdi,%rax), %xmm0
86 ; BASE-NEXT:    movupd 524288(%rsi,%rax), %xmm1
87 ; BASE-NEXT:    maxpd %xmm0, %xmm1
88 ; BASE-NEXT:    movupd %xmm1, 524288(%rdi,%rax)
89 ; BASE-NEXT:    addq $16, %rax
90 ; BASE-NEXT:    jne .LBB0_1
91 ; BASE-NEXT:  # %bb.2: # %exit
92 ; BASE-NEXT:    retq
93 ; FUSE-LABEL: maxArray:
94 ; FUSE:       # %bb.0: # %entry
95 ; FUSE-NEXT:    xorl %eax, %eax
96 ; FUSE-NEXT:    .p2align 4, 0x90
97 ; FUSE-NEXT:  .LBB0_1: # %vector.body
98 ; FUSE-NEXT:    # =>This Inner Loop Header: Depth=1
99 ; FUSE-NEXT:    movupd (%rdi,%rax,8), %xmm0
100 ; FUSE-NEXT:    movupd (%rsi,%rax,8), %xmm1
101 ; FUSE-NEXT:    maxpd %xmm0, %xmm1
102 ; FUSE-NEXT:    movupd %xmm1, (%rdi,%rax,8)
103 ; FUSE-NEXT:    addq $2, %rax
104 ; FUSE-NEXT:    cmpq $65536, %rax # imm = 0x10000
105 ; FUSE-NEXT:    jne .LBB0_1
106 ; FUSE-NEXT:  # %bb.2: # %exit
107 ; FUSE-NEXT:    retq
108 entry:
109   br label %vector.body
111 vector.body:
112   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
113   %gepx = getelementptr inbounds double, ptr %x, i64 %index
114   %gepy = getelementptr inbounds double, ptr %y, i64 %index
115   %xval = load <2 x double>, ptr %gepx, align 8
116   %yval = load <2 x double>, ptr %gepy, align 8
117   %cmp = fcmp ogt <2 x double> %yval, %xval
118   %max = select <2 x i1> %cmp, <2 x double> %yval, <2 x double> %xval
119   store <2 x double> %max, ptr %gepx, align 8
120   %index.next = add i64 %index, 2
121   %done = icmp eq i64 %index.next, 65536
122   br i1 %done, label %exit, label %vector.body
124 exit:
125   ret void