[x86] promote 'add nsw' to a wider type to allow more combines · llvm/llvm-project@bbd5244 (original) (raw)
1
1
`; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
`
2
2
``
3
3
`; The fundamental problem: an add separated from other arithmetic by a sext can't
`
4
``
`-
; be combined with the later instructions. However, if the first add is 'nsw',
`
``
4
`+
; be combined with the later instructions. However, if the first add is 'nsw',
`
5
5
`; then we can promote the sext ahead of that add to allow optimizations.
`
6
6
``
7
7
`define i64 @add_nsw_consts(i32 %i) {
`
8
8
`; CHECK-LABEL: add_nsw_consts:
`
9
9
`; CHECK: # BB#0:
`
10
``
`-
; CHECK-NEXT: addl $5, %edi
`
11
10
`; CHECK-NEXT: movslq %edi, %rax
`
12
``
`-
; CHECK-NEXT: addq $7, %rax
`
``
11
`+
; CHECK-NEXT: addq $12, %rax
`
13
12
`; CHECK-NEXT: retq
`
14
13
``
15
14
`%add = add nsw i32 %i, 5
`
`@@ -24,9 +23,8 @@ define i64 @add_nsw_consts(i32 %i) {
`
24
23
`define i64 @add_nsw_sext_add(i32 %i, i64 %x) {
`
25
24
`; CHECK-LABEL: add_nsw_sext_add:
`
26
25
`; CHECK: # BB#0:
`
27
``
`-
; CHECK-NEXT: addl $5, %edi
`
28
26
`; CHECK-NEXT: movslq %edi, %rax
`
29
``
`-
; CHECK-NEXT: addq %rsi, %rax
`
``
27
`+
; CHECK-NEXT: leaq 5(%rax,%rsi), %rax
`
30
28
`; CHECK-NEXT: retq
`
31
29
``
32
30
`%add = add nsw i32 %i, 5
`
`@@ -41,9 +39,8 @@ define i64 @add_nsw_sext_add(i32 %i, i64 %x) {
`
41
39
`define i64 @add_nsw_sext_lsh_add(i32 %i, i64 %x) {
`
42
40
`; CHECK-LABEL: add_nsw_sext_lsh_add:
`
43
41
`; CHECK: # BB#0:
`
44
``
`-
; CHECK-NEXT: addl $-5, %edi
`
45
42
`; CHECK-NEXT: movslq %edi, %rax
`
46
``
`-
; CHECK-NEXT: leaq (%rsi,%rax,8), %rax
`
``
43
`+
; CHECK-NEXT: leaq -40(%rsi,%rax,8), %rax
`
47
44
`; CHECK-NEXT: retq
`
48
45
``
49
46
`%add = add nsw i32 %i, -5
`
`@@ -73,9 +70,8 @@ define i64 @add_nsw_sext(i32 %i, i64 %x) {
`
73
70
`define i8* @gep8(i32 %i, i8* %x) {
`
74
71
`; CHECK-LABEL: gep8:
`
75
72
`; CHECK: # BB#0:
`
76
``
`-
; CHECK-NEXT: addl $5, %edi
`
77
73
`; CHECK-NEXT: movslq %edi, %rax
`
78
``
`-
; CHECK-NEXT: addq %rsi, %rax
`
``
74
`+
; CHECK-NEXT: leaq 5(%rax,%rsi), %rax
`
79
75
`; CHECK-NEXT: retq
`
80
76
``
81
77
`%add = add nsw i32 %i, 5
`
`@@ -87,9 +83,8 @@ define i8* @gep8(i32 %i, i8* %x) {
`
87
83
`define i16* @gep16(i32 %i, i16* %x) {
`
88
84
`; CHECK-LABEL: gep16:
`
89
85
`; CHECK: # BB#0:
`
90
``
`-
; CHECK-NEXT: addl $-5, %edi
`
91
86
`; CHECK-NEXT: movslq %edi, %rax
`
92
``
`-
; CHECK-NEXT: leaq (%rsi,%rax,2), %rax
`
``
87
`+
; CHECK-NEXT: leaq -10(%rsi,%rax,2), %rax
`
93
88
`; CHECK-NEXT: retq
`
94
89
``
95
90
`%add = add nsw i32 %i, -5
`
`@@ -101,9 +96,8 @@ define i16* @gep16(i32 %i, i16* %x) {
`
101
96
`define i32* @gep32(i32 %i, i32* %x) {
`
102
97
`; CHECK-LABEL: gep32:
`
103
98
`; CHECK: # BB#0:
`
104
``
`-
; CHECK-NEXT: addl $5, %edi
`
105
99
`; CHECK-NEXT: movslq %edi, %rax
`
106
``
`-
; CHECK-NEXT: leaq (%rsi,%rax,4), %rax
`
``
100
`+
; CHECK-NEXT: leaq 20(%rsi,%rax,4), %rax
`
107
101
`; CHECK-NEXT: retq
`
108
102
``
109
103
`%add = add nsw i32 %i, 5
`
`@@ -115,9 +109,8 @@ define i32* @gep32(i32 %i, i32* %x) {
`
115
109
`define i64* @gep64(i32 %i, i64* %x) {
`
116
110
`; CHECK-LABEL: gep64:
`
117
111
`; CHECK: # BB#0:
`
118
``
`-
; CHECK-NEXT: addl $-5, %edi
`
119
112
`; CHECK-NEXT: movslq %edi, %rax
`
120
``
`-
; CHECK-NEXT: leaq (%rsi,%rax,8), %rax
`
``
113
`+
; CHECK-NEXT: leaq -40(%rsi,%rax,8), %rax
`
121
114
`; CHECK-NEXT: retq
`
122
115
``
123
116
`%add = add nsw i32 %i, -5
`
`@@ -131,10 +124,9 @@ define i64* @gep64(i32 %i, i64* %x) {
`
131
124
`define i128* @gep128(i32 %i, i128* %x) {
`
132
125
`; CHECK-LABEL: gep128:
`
133
126
`; CHECK: # BB#0:
`
134
``
`-
; CHECK-NEXT: addl $5, %edi
`
135
127
`; CHECK-NEXT: movslq %edi, %rax
`
136
128
`; CHECK-NEXT: shlq $4, %rax
`
137
``
`-
; CHECK-NEXT: addq %rsi, %rax
`
``
129
`+
; CHECK-NEXT: leaq 80(%rax,%rsi), %rax
`
138
130
`; CHECK-NEXT: retq
`
139
131
``
140
132
`%add = add nsw i32 %i, 5
`
`@@ -150,14 +142,10 @@ define i128* @gep128(i32 %i, i128* %x) {
`
150
142
`define void @PR20134(i32* %a, i32 %i) {
`
151
143
`; CHECK-LABEL: PR20134:
`
152
144
`; CHECK: # BB#0:
`
153
``
`-
; CHECK-NEXT: leal 1(%rsi), %eax
`
154
``
`-
; CHECK-NEXT: cltq
`
155
``
`-
; CHECK-NEXT: movl (%rdi,%rax,4), %eax
`
156
``
`-
; CHECK-NEXT: leal 2(%rsi), %ecx
`
157
``
`-
; CHECK-NEXT: movslq %ecx, %rcx
`
158
``
`-
; CHECK-NEXT: addl (%rdi,%rcx,4), %eax
`
159
``
`-
; CHECK-NEXT: movslq %esi, %rcx
`
160
``
`-
; CHECK-NEXT: movl %eax, (%rdi,%rcx,4)
`
``
145
`+
; CHECK-NEXT: movslq %esi, %rax
`
``
146
`+
; CHECK-NEXT: movl 4(%rdi,%rax,4), %ecx
`
``
147
`+
; CHECK-NEXT: addl 8(%rdi,%rax,4), %ecx
`
``
148
`+
; CHECK-NEXT: movl %ecx, (%rdi,%rax,4)
`
161
149
`; CHECK-NEXT: retq
`
162
150
``
163
151
`%add1 = add nsw i32 %i, 1
`