[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

`