Skip to content

Commit 9103b1d

Browse files
authored
[DAG] Extend the computeOverflowForSignedSub/computeOverflowForUnsignedSub implementations with ConstantRange (#67890)
- Add tests for computeOverflowFor*Sub functions - extend the computeOverflowForSignedSub/computeOverflowForUnsignedSub implementations with ConstantRange (#37109)
1 parent 04b403d commit 9103b1d

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4091,8 +4091,11 @@ SelectionDAG::computeOverflowForSignedSub(SDValue N0, SDValue N1) const {
40914091
if (ComputeNumSignBits(N0) > 1 && ComputeNumSignBits(N1) > 1)
40924092
return OFK_Never;
40934093

4094-
// TODO: Add ConstantRange::signedSubMayOverflow handling.
4095-
return OFK_Sometime;
4094+
KnownBits N0Known = computeKnownBits(N0);
4095+
KnownBits N1Known = computeKnownBits(N1);
4096+
ConstantRange N0Range = ConstantRange::fromKnownBits(N0Known, true);
4097+
ConstantRange N1Range = ConstantRange::fromKnownBits(N1Known, true);
4098+
return mapOverflowResult(N0Range.signedSubMayOverflow(N1Range));
40964099
}
40974100

40984101
SelectionDAG::OverflowKind
@@ -4101,8 +4104,11 @@ SelectionDAG::computeOverflowForUnsignedSub(SDValue N0, SDValue N1) const {
41014104
if (isNullConstant(N1))
41024105
return OFK_Never;
41034106

4104-
// TODO: Add ConstantRange::unsignedSubMayOverflow handling.
4105-
return OFK_Sometime;
4107+
KnownBits N0Known = computeKnownBits(N0);
4108+
KnownBits N1Known = computeKnownBits(N1);
4109+
ConstantRange N0Range = ConstantRange::fromKnownBits(N0Known, false);
4110+
ConstantRange N1Range = ConstantRange::fromKnownBits(N1Known, false);
4111+
return mapOverflowResult(N0Range.unsignedSubMayOverflow(N1Range));
41064112
}
41074113

41084114
SelectionDAG::OverflowKind

llvm/test/CodeGen/X86/combine-subo.ll

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44

55
declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
66
declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
7+
declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone
8+
declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone
9+
710

811
declare {<4 x i32>, <4 x i1>} @llvm.ssub.with.overflow.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
912
declare {<4 x i32>, <4 x i1>} @llvm.usub.with.overflow.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
13+
declare { <4 x i8>, <4 x i1> } @llvm.ssub.with.overflow.v4i8(<4 x i8>, <4 x i8>) nounwind readnone
14+
declare { <4 x i8>, <4 x i1> } @llvm.usub.with.overflow.v4i8(<4 x i8> , <4 x i8>) nounwind readnone
1015

1116
; fold (ssub x, 0) -> x
1217
define i32 @combine_ssub_zero(i32 %a0, i32 %a1) {
@@ -148,3 +153,79 @@ define <4 x i32> @combine_vec_usub_negone(<4 x i32> %a0, <4 x i32> %a1) {
148153
%4 = select <4 x i1> %3, <4 x i32> %a1, <4 x i32> %2
149154
ret <4 x i32> %4
150155
}
156+
157+
define { i32, i1 } @combine_usub_nuw(i32 %a, i32 %b) {
158+
; CHECK-LABEL: combine_usub_nuw:
159+
; CHECK: # %bb.0:
160+
; CHECK-NEXT: movl %edi, %eax
161+
; CHECK-NEXT: orl $-2147483648, %eax # imm = 0x80000000
162+
; CHECK-NEXT: andl $2147483647, %esi # imm = 0x7FFFFFFF
163+
; CHECK-NEXT: subl %esi, %eax
164+
; CHECK-NEXT: xorl %edx, %edx
165+
; CHECK-NEXT: retq
166+
%aa = or i32 %a, 2147483648
167+
%bb = and i32 %b, 2147483647
168+
%x = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %aa, i32 %bb)
169+
ret { i32, i1 } %x
170+
}
171+
172+
define { i8, i1 } @usub_always_overflow(i8 %x) nounwind {
173+
; CHECK-LABEL: usub_always_overflow:
174+
; CHECK: # %bb.0:
175+
; CHECK-NEXT: orb $64, %dil
176+
; CHECK-NEXT: movb $63, %al
177+
; CHECK-NEXT: subb %dil, %al
178+
; CHECK-NEXT: setb %dl
179+
; CHECK-NEXT: retq
180+
%y = or i8 %x, 64
181+
%a = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 63, i8 %y)
182+
ret { i8, i1 } %a
183+
}
184+
185+
define { i8, i1 } @ssub_always_overflow(i8 %x) nounwind {
186+
; CHECK-LABEL: ssub_always_overflow:
187+
; CHECK: # %bb.0:
188+
; CHECK-NEXT: cmpb $30, %dil
189+
; CHECK-NEXT: movl $29, %ecx
190+
; CHECK-NEXT: cmovgel %edi, %ecx
191+
; CHECK-NEXT: movb $-100, %al
192+
; CHECK-NEXT: subb %cl, %al
193+
; CHECK-NEXT: seto %dl
194+
; CHECK-NEXT: retq
195+
%c = icmp sgt i8 %x, 29
196+
%y = select i1 %c, i8 %x, i8 29
197+
%a = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 -100, i8 %y)
198+
ret { i8, i1 } %a
199+
}
200+
201+
define { <4 x i8>, <4 x i1> } @always_usub_const_vector() nounwind {
202+
; SSE-LABEL: always_usub_const_vector:
203+
; SSE: # %bb.0:
204+
; SSE-NEXT: pcmpeqd %xmm0, %xmm0
205+
; SSE-NEXT: pcmpeqd %xmm1, %xmm1
206+
; SSE-NEXT: retq
207+
;
208+
; AVX-LABEL: always_usub_const_vector:
209+
; AVX: # %bb.0:
210+
; AVX-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0
211+
; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
212+
; AVX-NEXT: retq
213+
%x = call { <4 x i8>, <4 x i1> } @llvm.usub.with.overflow.v4i8(<4 x i8> <i8 0, i8 0, i8 0, i8 0>, <4 x i8> <i8 1, i8 1, i8 1, i8 1>)
214+
ret { <4 x i8>, <4 x i1> } %x
215+
}
216+
217+
define { <4 x i8>, <4 x i1> } @never_usub_const_vector() nounwind {
218+
; SSE-LABEL: never_usub_const_vector:
219+
; SSE: # %bb.0:
220+
; SSE-NEXT: movaps {{.*#+}} xmm0 = <127,255,0,254,u,u,u,u,u,u,u,u,u,u,u,u>
221+
; SSE-NEXT: xorps %xmm1, %xmm1
222+
; SSE-NEXT: retq
223+
;
224+
; AVX-LABEL: never_usub_const_vector:
225+
; AVX: # %bb.0:
226+
; AVX-NEXT: vbroadcastss {{.*#+}} xmm0 = [127,255,0,254,127,255,0,254,127,255,0,254,127,255,0,254]
227+
; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1
228+
; AVX-NEXT: retq
229+
%x = call { <4 x i8>, <4 x i1> } @llvm.usub.with.overflow.v4i8(<4 x i8> <i8 255, i8 255, i8 255, i8 255>, <4 x i8> <i8 128, i8 0, i8 255, i8 1>)
230+
ret { <4 x i8>, <4 x i1> } %x
231+
}

llvm/test/CodeGen/X86/or-with-overflow.ll

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,13 @@ define i32 @or_i32_rr(i32 %0, i32 %1) {
161161
define i64 @or_i64_ri(i64 %0, i64 %1) nounwind {
162162
; X86-LABEL: or_i64_ri:
163163
; X86: # %bb.0:
164-
; X86-NEXT: pushl %esi
165164
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
166165
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
167-
; X86-NEXT: movl %eax, %ecx
168-
; X86-NEXT: orl $17, %ecx
169-
; X86-NEXT: cmpl $1, %ecx
170-
; X86-NEXT: movl %edx, %esi
171-
; X86-NEXT: sbbl $0, %esi
172-
; X86-NEXT: jl .LBB6_2
166+
; X86-NEXT: testl %edx, %edx
167+
; X86-NEXT: js .LBB6_2
173168
; X86-NEXT: # %bb.1:
174-
; X86-NEXT: movl %ecx, %eax
169+
; X86-NEXT: orl $17, %eax
175170
; X86-NEXT: .LBB6_2:
176-
; X86-NEXT: popl %esi
177171
; X86-NEXT: retl
178172
;
179173
; X64-LABEL: or_i64_ri:

0 commit comments

Comments
 (0)