forked from OSchip/llvm-project
Recommit r333226 "[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive."
Libfuzzer tests have been fixed to prevent being optimized. Original commit message: 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. N Differential Revision: https://reviews.llvm.org/D47041 llvm-svn: 333300
This commit is contained in:
parent
39bf7d551b
commit
8f77dcadff
|
@ -1078,6 +1078,12 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
|
||||||
// leading zero bits.
|
// leading zero bits.
|
||||||
MaxHighZeros =
|
MaxHighZeros =
|
||||||
std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
|
std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
|
||||||
|
} else if (SPF == SPF_ABS) {
|
||||||
|
// RHS from matchSelectPattern returns the negation part of abs pattern.
|
||||||
|
// If the negate has an NSW flag we can assume the sign bit of the result
|
||||||
|
// will be 0 because that makes abs(INT_MIN) undefined.
|
||||||
|
if (cast<Instruction>(RHS)->hasNoSignedWrap())
|
||||||
|
MaxHighZeros = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only known if known in both the LHS and RHS.
|
// Only known if known in both the LHS and RHS.
|
||||||
|
|
|
@ -293,3 +293,14 @@ define <2 x i8> @negate_nabs(<2 x i8> %x) {
|
||||||
%r = sub <2 x i8> zeroinitializer, %s
|
%r = sub <2 x i8> zeroinitializer, %s
|
||||||
ret <2 x i8> %r
|
ret <2 x i8> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i1 @abs_must_be_positive(i32 %x) {
|
||||||
|
; CHECK-LABEL: @abs_must_be_positive(
|
||||||
|
; CHECK-NEXT: ret i1 true
|
||||||
|
;
|
||||||
|
%negx = sub nsw i32 0, %x
|
||||||
|
%c = icmp sge i32 %x, 0
|
||||||
|
%sel = select i1 %c, i32 %x, i32 %negx
|
||||||
|
%c2 = icmp sge i32 %sel, 0
|
||||||
|
ret i1 %c2
|
||||||
|
}
|
||||||
|
|
|
@ -933,8 +933,8 @@ define i32 @nabs_abs_x09(i32 %x) {
|
||||||
; CHECK-LABEL: @nabs_abs_x09(
|
; CHECK-LABEL: @nabs_abs_x09(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
||||||
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||||
; CHECK-NEXT: ret i32 [[COND1]]
|
; CHECK-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
%cmp = icmp sgt i32 %x, -1
|
%cmp = icmp sgt i32 %x, -1
|
||||||
%sub = sub nsw i32 0, %x
|
%sub = sub nsw i32 0, %x
|
||||||
|
@ -949,8 +949,8 @@ define i32 @nabs_abs_x10(i32 %x) {
|
||||||
; CHECK-LABEL: @nabs_abs_x10(
|
; CHECK-LABEL: @nabs_abs_x10(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
||||||
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||||
; CHECK-NEXT: ret i32 [[COND1]]
|
; CHECK-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
%cmp = icmp sgt i32 %x, 0
|
%cmp = icmp sgt i32 %x, 0
|
||||||
%sub = sub nsw i32 0, %x
|
%sub = sub nsw i32 0, %x
|
||||||
|
@ -965,8 +965,8 @@ define i32 @nabs_abs_x11(i32 %x) {
|
||||||
; CHECK-LABEL: @nabs_abs_x11(
|
; CHECK-LABEL: @nabs_abs_x11(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
||||||
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||||
; CHECK-NEXT: ret i32 [[COND1]]
|
; CHECK-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
%cmp = icmp slt i32 %x, 0
|
%cmp = icmp slt i32 %x, 0
|
||||||
%sub = sub nsw i32 0, %x
|
%sub = sub nsw i32 0, %x
|
||||||
|
@ -981,8 +981,8 @@ define i32 @nabs_abs_x12(i32 %x) {
|
||||||
; CHECK-LABEL: @nabs_abs_x12(
|
; CHECK-LABEL: @nabs_abs_x12(
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[X]]
|
||||||
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[SUB]]
|
||||||
; CHECK-NEXT: ret i32 [[COND1]]
|
; CHECK-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
%cmp = icmp slt i32 %x, 1
|
%cmp = icmp slt i32 %x, 1
|
||||||
%sub = sub nsw i32 0, %x
|
%sub = sub nsw i32 0, %x
|
||||||
|
|
Loading…
Reference in New Issue