Skip to content

Commit 49f23fe

Browse files
committedMay 24, 2018
[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive.
If the nsw flag is used in the absolute value then it is undefined for INT_MIN. For all other value it will produce a positive number. So we can assume the result is positive. This breaks some InstCombine abs/nabs combining tests because we simplify the second compare from known bits rather than as the whole pattern. Looks like we can probably fix it by adding a neg+abs/nabs combine to just swap the select operands. Need to check alive to make sure there are no corner cases. Differential Revision: https://reviews.llvm.org/D47041 llvm-svn: 333226
1 parent 6da6f43 commit 49f23fe

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed
 

‎llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,12 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
10781078
// leading zero bits.
10791079
MaxHighZeros =
10801080
std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
1081+
} else if (SPF == SPF_ABS) {
1082+
// RHS from matchSelectPattern returns the negation part of abs pattern.
1083+
// If the negate has an NSW flag we can assume the sign bit of the result
1084+
// will be 0 because that makes abs(INT_MIN) undefined.
1085+
if (cast<Instruction>(RHS)->hasNoSignedWrap())
1086+
MaxHighZeros = 1;
10811087
}
10821088

10831089
// Only known if known in both the LHS and RHS.

‎llvm/test/Transforms/InstCombine/abs-1.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,14 @@ define <2 x i8> @negate_nabs(<2 x i8> %x) {
293293
%r = sub <2 x i8> zeroinitializer, %s
294294
ret <2 x i8> %r
295295
}
296+
297+
define i1 @abs_must_be_positive(i32 %x) {
298+
; CHECK-LABEL: @abs_must_be_positive(
299+
; CHECK-NEXT: ret i1 true
300+
;
301+
%negx = sub nsw i32 0, %x
302+
%c = icmp sge i32 %x, 0
303+
%sel = select i1 %c, i32 %x, i32 %negx
304+
%c2 = icmp sge i32 %sel, 0
305+
ret i1 %c2
306+
}

‎llvm/test/Transforms/InstCombine/abs_abs.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -933,8 +933,8 @@ define i32 @nabs_abs_x09(i32 %x) {
933933
; CHECK-LABEL: @nabs_abs_x09(
934934
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
935935
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
936-
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
937-
; CHECK-NEXT: ret i32 [[COND1]]
936+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
937+
; CHECK-NEXT: ret i32 [[COND]]
938938
;
939939
%cmp = icmp sgt i32 %x, -1
940940
%sub = sub nsw i32 0, %x
@@ -949,8 +949,8 @@ define i32 @nabs_abs_x10(i32 %x) {
949949
; CHECK-LABEL: @nabs_abs_x10(
950950
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
951951
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
952-
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
953-
; CHECK-NEXT: ret i32 [[COND1]]
952+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
953+
; CHECK-NEXT: ret i32 [[COND]]
954954
;
955955
%cmp = icmp sgt i32 %x, 0
956956
%sub = sub nsw i32 0, %x
@@ -965,8 +965,8 @@ define i32 @nabs_abs_x11(i32 %x) {
965965
; CHECK-LABEL: @nabs_abs_x11(
966966
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
967967
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
968-
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
969-
; CHECK-NEXT: ret i32 [[COND1]]
968+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
969+
; CHECK-NEXT: ret i32 [[COND]]
970970
;
971971
%cmp = icmp slt i32 %x, 0
972972
%sub = sub nsw i32 0, %x
@@ -981,8 +981,8 @@ define i32 @nabs_abs_x12(i32 %x) {
981981
; CHECK-LABEL: @nabs_abs_x12(
982982
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
983983
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
984-
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
985-
; CHECK-NEXT: ret i32 [[COND1]]
984+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
985+
; CHECK-NEXT: ret i32 [[COND]]
986986
;
987987
%cmp = icmp slt i32 %x, 1
988988
%sub = sub nsw i32 0, %x

0 commit comments

Comments
 (0)
Please sign in to comment.