1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[InstCombine] fix profitability equation for max-of-nots transform

As the test change shows, we can increase the critical path by adding
a 'not' instruction, so make sure that we're actually removing an
instruction if we do this transform.

This transform could also cause us to miss folds of min/max pairs.

llvm-svn: 286315
This commit is contained in:
Sanjay Patel 2016-11-09 00:13:11 +00:00
parent 8021633552
commit b8d6170e09
2 changed files with 13 additions and 12 deletions

View File

@ -1308,15 +1308,14 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
if ((SPF == SPF_SMAX || SPF == SPF_UMAX) &&
IsFreeToInvert(LHS, LHS->hasNUses(2)) &&
IsFreeToInvert(RHS, RHS->hasNUses(2))) {
// This transform adds a not operation, and that extra cost needs to be
// justified. We look for simplifications that will result from applying
// this rule:
bool Profitable =
(LHS->hasNUses(2) && match(LHS, m_Not(m_Value()))) ||
(RHS->hasNUses(2) && match(RHS, m_Not(m_Value()))) ||
// For this transform to be profitable, we need to eliminate at least two
// 'not' instructions if we're going to add one 'not' instruction.
int NumberOfNots =
(LHS->hasNUses(2) && match(LHS, m_Not(m_Value()))) +
(RHS->hasNUses(2) && match(RHS, m_Not(m_Value()))) +
(SI.hasOneUse() && match(*SI.user_begin(), m_Not(m_Value())));
if (Profitable) {
if (NumberOfNots >= 2) {
Value *NewLHS = Builder->CreateNot(LHS);
Value *NewRHS = Builder->CreateNot(RHS);
Value *NewCmp = SPF == SPF_SMAX

View File

@ -34,13 +34,15 @@ define i32 @compute_min_3(i32 %x, i32 %y, i32 %z) {
ret i32 %min
}
; Don't increase the critical path by moving the 'not' op after the 'select'.
define i32 @compute_min_arithmetic(i32 %x, i32 %y) {
; CHECK-LABEL: @compute_min_arithmetic(
; CHECK-NEXT: [[TMP1:%.*]] = add i32 %x, -4
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP1]], %y
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 %y
; CHECK-NEXT: [[TMP4:%.*]] = xor i32 [[TMP3]], -1
; CHECK-NEXT: ret i32 [[TMP4]]
; CHECK-NEXT: [[NOT_VALUE:%.*]] = sub i32 3, %x
; CHECK-NEXT: [[NOT_Y:%.*]] = xor i32 %y, -1
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[NOT_VALUE]], [[NOT_Y]]
; CHECK-NEXT: [[NOT_MIN:%.*]] = select i1 [[CMP]], i32 [[NOT_VALUE]], i32 [[NOT_Y]]
; CHECK-NEXT: ret i32 [[NOT_MIN]]
;
%not_value = sub i32 3, %x
%not_y = sub i32 -1, %y