mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 04:28:30 +00:00
[SLSR] handle (B | i) * S
Summary: Consider (B | i) * S as (B + i) * S if B and i have no bits set in common. Test Plan: @or in slsr-mul.ll Reviewers: broune, meheff Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9788 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237456 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d63e0fc2d9
commit
ef0b6c4b1e
@ -61,6 +61,7 @@
|
|||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/Analysis/ScalarEvolution.h"
|
#include "llvm/Analysis/ScalarEvolution.h"
|
||||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
@ -404,20 +405,37 @@ void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForAdd(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if A matches B + C where C is constant.
|
||||||
|
static bool matchesAdd(Value *A, Value *&B, ConstantInt *&C) {
|
||||||
|
return (match(A, m_Add(m_Value(B), m_ConstantInt(C))) ||
|
||||||
|
match(A, m_Add(m_ConstantInt(C), m_Value(B))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if A matches B | C where C is constant.
|
||||||
|
static bool matchesOr(Value *A, Value *&B, ConstantInt *&C) {
|
||||||
|
return (match(A, m_Or(m_Value(B), m_ConstantInt(C))) ||
|
||||||
|
match(A, m_Or(m_ConstantInt(C), m_Value(B))));
|
||||||
|
}
|
||||||
|
|
||||||
void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
|
void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
|
||||||
Value *LHS, Value *RHS, Instruction *I) {
|
Value *LHS, Value *RHS, Instruction *I) {
|
||||||
Value *B = nullptr;
|
Value *B = nullptr;
|
||||||
ConstantInt *Idx = nullptr;
|
ConstantInt *Idx = nullptr;
|
||||||
if (match(LHS, m_Add(m_Value(B), m_ConstantInt(Idx))) ||
|
if (matchesAdd(LHS, B, Idx)) {
|
||||||
match(LHS, m_Add(m_ConstantInt(Idx), m_Value(B)))) {
|
|
||||||
// If LHS is in the form of "Base + Index", then I is in the form of
|
// If LHS is in the form of "Base + Index", then I is in the form of
|
||||||
// "(Base + Index) * RHS".
|
// "(Base + Index) * RHS".
|
||||||
allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(B), Idx, RHS, I);
|
allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(B), Idx, RHS, I);
|
||||||
|
} else if (matchesOr(LHS, B, Idx) && haveNoCommonBitsSet(B, Idx, *DL)) {
|
||||||
|
// If LHS is in the form of "Base | Index" and Base and Index have no common
|
||||||
|
// bits set, then
|
||||||
|
// Base | Index = Base + Index
|
||||||
|
// and I is thus in the form of "(Base + Index) * RHS".
|
||||||
|
allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(B), Idx, RHS, I);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, at least try the form (LHS + 0) * RHS.
|
// Otherwise, at least try the form (LHS + 0) * RHS.
|
||||||
ConstantInt *Zero = ConstantInt::get(cast<IntegerType>(I->getType()), 0);
|
ConstantInt *Zero = ConstantInt::get(cast<IntegerType>(I->getType()), 0);
|
||||||
allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(LHS), Zero, RHS,
|
allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(LHS), Zero, RHS,
|
||||||
I);
|
I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,29 @@ define void @non_canonicalized(i32 %b, i32 %s) {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @or(i32 %a, i32 %s) {
|
||||||
|
%b = shl i32 %a, 1
|
||||||
|
; CHECK-LABEL: @or(
|
||||||
|
; foo(b * s);
|
||||||
|
%mul0 = mul i32 %b, %s
|
||||||
|
; CHECK: [[base:[^ ]+]] = mul i32
|
||||||
|
call void @foo(i32 %mul0)
|
||||||
|
|
||||||
|
; foo((b | 1) * s);
|
||||||
|
%b1 = or i32 %b, 1
|
||||||
|
%mul1 = mul i32 %b1, %s
|
||||||
|
; CHECK: add i32 [[base]], %s
|
||||||
|
call void @foo(i32 %mul1)
|
||||||
|
|
||||||
|
; foo((b | 2) * s);
|
||||||
|
%b2 = or i32 %b, 2
|
||||||
|
%mul2 = mul i32 %b2, %s
|
||||||
|
; CHECK: mul i32 %b2, %s
|
||||||
|
call void @foo(i32 %mul2)
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
; foo(a * b)
|
; foo(a * b)
|
||||||
; foo((a + 1) * b)
|
; foo((a + 1) * b)
|
||||||
; foo(a * (b + 1))
|
; foo(a * (b + 1))
|
||||||
|
Loading…
Reference in New Issue
Block a user