xref: /llvm-project/llvm/test/CodeGen/X86/machine-cse.ll (revision e6bf48d11047e970cb24554a01b65b566d6b5d22)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
3; RUN: llc -mtriple=x86_64-unknown-unknown -early-live-intervals < %s | FileCheck %s
4; rdar://7610418
5
6%ptr = type { ptr }
7%struct.s1 = type { %ptr, %ptr }
8%struct.s2 = type { i32, ptr, ptr, [256 x ptr], [8 x i32], i64, ptr, i32, i64, i64, i32, ptr, ptr, [49 x i64] }
9%struct.s3 = type { ptr, ptr, i32, i32, i32 }
10
11define fastcc ptr @t(i32 %base) nounwind {
12; CHECK-LABEL: t:
13; CHECK:       # %bb.0: # %entry
14; CHECK-NEXT:    pushq %rax
15; CHECK-NEXT:    movl %edi, %eax
16; CHECK-NEXT:    shlq $9, %rax
17; CHECK-NEXT:    leaq (%rax,%rax,4), %rdi
18; CHECK-NEXT:    xorl %eax, %eax
19; CHECK-NEXT:    testb %al, %al
20; CHECK-NEXT:    jne .LBB0_2
21; CHECK-NEXT:  # %bb.1: # %bb1
22; CHECK-NEXT:    callq bar@PLT
23; CHECK-NEXT:  .LBB0_2: # %bb2
24; CHECK-NEXT:    callq foo@PLT
25entry:
26  %0 = zext i32 %base to i64
27  %1 = getelementptr inbounds %struct.s2, ptr null, i64 %0
28  br i1 undef, label %bb1, label %bb2
29
30bb1:
31  %2 = getelementptr inbounds %struct.s2, ptr null, i64 %0, i32 0
32  call void @bar(ptr %2) nounwind
33  unreachable
34
35bb2:
36  %3 = call fastcc ptr @foo(ptr %1) nounwind
37  unreachable
38
39bb3:
40  ret ptr undef
41}
42
43declare void @bar(ptr)
44
45declare fastcc ptr @foo(ptr) nounwind
46
47; rdar://8773371
48
49declare void @printf(...) nounwind
50
51define void @commute(i32 %test_case, i32 %scale) nounwind ssp {
52; CHECK-LABEL: commute:
53; CHECK:       # %bb.0: # %entry
54; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
55; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
56; CHECK-NEXT:    leal -1(%rdi), %eax
57; CHECK-NEXT:    cmpl $2, %eax
58; CHECK-NEXT:    ja .LBB1_4
59; CHECK-NEXT:  # %bb.1: # %sw.bb
60; CHECK-NEXT:    xorl %eax, %eax
61; CHECK-NEXT:    testb %al, %al
62; CHECK-NEXT:    jne .LBB1_4
63; CHECK-NEXT:  # %bb.2: # %if.end34
64; CHECK-NEXT:    pushq %rax
65; CHECK-NEXT:    imull %edi, %esi
66; CHECK-NEXT:    leal (%rsi,%rsi,2), %esi
67; CHECK-NEXT:    # kill: def $edi killed $edi killed $rdi
68; CHECK-NEXT:    xorl %eax, %eax
69; CHECK-NEXT:    callq printf@PLT
70; CHECK-NEXT:    addq $8, %rsp
71; CHECK-NEXT:    .p2align 4
72; CHECK-NEXT:  .LBB1_3: # %for.body53.us
73; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
74; CHECK-NEXT:    jmp .LBB1_3
75; CHECK-NEXT:  .LBB1_4: # %sw.bb307
76; CHECK-NEXT:    retq
77entry:
78  switch i32 %test_case, label %sw.bb307 [
79    i32 1, label %sw.bb
80    i32 2, label %sw.bb
81    i32 3, label %sw.bb
82  ]
83
84sw.bb:
85  %mul = mul nsw i32 %test_case, 3
86  %mul20 = mul nsw i32 %mul, %scale
87  br i1 undef, label %if.end34, label %sw.bb307
88
89if.end34:
90  tail call void (...) @printf(i32 %test_case, i32 %mul20) nounwind
91  %tmp = mul i32 %scale, %test_case
92  %tmp752 = mul i32 %tmp, 3
93  %tmp753 = zext i32 %tmp752 to i64
94  br label %bb.nph743.us
95
96for.body53.us:
97  %exitcond = icmp eq i64 undef, %tmp753
98  br i1 %exitcond, label %bb.nph743.us, label %for.body53.us
99
100bb.nph743.us:
101  br label %for.body53.us
102
103sw.bb307:
104  ret void
105}
106
107; CSE physical register defining instruction across MBB boundary.
108; rdar://10660865
109define i32 @cross_mbb_phys_cse(i32 %a, i32 %b) nounwind ssp {
110; CHECK-LABEL: cross_mbb_phys_cse:
111; CHECK:       # %bb.0: # %entry
112; CHECK-NEXT:    movl $1, %eax
113; CHECK-NEXT:    cmpl %esi, %edi
114; CHECK-NEXT:    ja .LBB2_2
115; CHECK-NEXT:  # %bb.1: # %if.end
116; CHECK-NEXT:    xorl %eax, %eax
117; CHECK-NEXT:    cmpl %esi, %edi
118; CHECK-NEXT:    sbbl %eax, %eax
119; CHECK-NEXT:  .LBB2_2: # %return
120; CHECK-NEXT:    retq
121entry:
122  %cmp = icmp ugt i32 %a, %b
123  br i1 %cmp, label %return, label %if.end
124
125if.end:
126  %cmp1 = icmp ult i32 %a, %b
127  %. = sext i1 %cmp1 to i32
128  br label %return
129
130return:
131  %retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ]
132  ret i32 %retval.0
133}
134
135; rdar://11393714
136define ptr @bsd_memchr(ptr %s, i32 %a, i32 %c, i64 %n) nounwind ssp {
137; CHECK-LABEL: bsd_memchr:
138; CHECK:       # %bb.0: # %entry
139; CHECK-NEXT:    testq %rcx, %rcx
140; CHECK-NEXT:    je .LBB3_4
141; CHECK-NEXT:  # %bb.1: # %preheader
142; CHECK-NEXT:    movq %rdi, %rax
143; CHECK-NEXT:    movzbl %dl, %edx
144; CHECK-NEXT:    .p2align 4
145; CHECK-NEXT:  .LBB3_2: # %do.body
146; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
147; CHECK-NEXT:    cmpl %edx, %esi
148; CHECK-NEXT:    je .LBB3_5
149; CHECK-NEXT:  # %bb.3: # %do.cond
150; CHECK-NEXT:    # in Loop: Header=BB3_2 Depth=1
151; CHECK-NEXT:    incq %rax
152; CHECK-NEXT:    decq %rcx
153; CHECK-NEXT:    jne .LBB3_2
154; CHECK-NEXT:  .LBB3_4:
155; CHECK-NEXT:    xorl %eax, %eax
156; CHECK-NEXT:  .LBB3_5: # %return
157; CHECK-NEXT:    retq
158entry:
159  %cmp = icmp eq i64 %n, 0
160  br i1 %cmp, label %return, label %preheader
161
162preheader:
163  %conv2 = and i32 %c, 255
164  br label %do.body
165
166do.body:
167  %n.addr.0 = phi i64 [ %dec, %do.cond ], [ %n, %preheader ]
168  %p.0 = phi ptr [ %incdec.ptr, %do.cond ], [ %s, %preheader ]
169  %cmp3 = icmp eq i32 %a, %conv2
170  br i1 %cmp3, label %return, label %do.cond
171
172do.cond:
173  %incdec.ptr = getelementptr inbounds i8, ptr %p.0, i64 1
174  %dec = add i64 %n.addr.0, -1
175  %cmp6 = icmp eq i64 %dec, 0
176  br i1 %cmp6, label %return, label %do.body
177
178return:
179  %retval.0 = phi ptr [ null, %entry ], [ null, %do.cond ], [ %p.0, %do.body ]
180  ret ptr %retval.0
181}
182
183; PR13578
184@t2_global = external dso_local global i32
185
186declare i1 @t2_func()
187
188define i32 @t2() nounwind {
189; CHECK-LABEL: t2:
190; CHECK:       # %bb.0:
191; CHECK-NEXT:    pushq %rax
192; CHECK-NEXT:    movl $42, t2_global(%rip)
193; CHECK-NEXT:    callq t2_func@PLT
194; CHECK-NEXT:    testb $1, %al
195; CHECK-NEXT:    je .LBB4_2
196; CHECK-NEXT:  # %bb.1: # %a
197; CHECK-NEXT:    movl t2_global(%rip), %eax
198; CHECK-NEXT:    popq %rcx
199; CHECK-NEXT:    retq
200; CHECK-NEXT:  .LBB4_2: # %b
201; CHECK-NEXT:    xorl %eax, %eax
202; CHECK-NEXT:    popq %rcx
203; CHECK-NEXT:    retq
204  store i32 42, ptr @t2_global
205  %c = call i1 @t2_func()
206  br i1 %c, label %a, label %b
207
208a:
209  %l = load i32, ptr @t2_global
210  ret i32 %l
211
212b:
213  ret i32 0
214}
215
216