mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[Reassociate] Guard add
-like or
conversion into an add
with profitability check
This is slightly better compile-time wise, since we avoid potentially-costly knownbits analysis that will ultimately not allow us to actually do anything with said `add`.
This commit is contained in:
parent
672cb989aa
commit
a30754006b
@ -920,6 +920,28 @@ static Value *NegateValue(Value *V, Instruction *BI,
|
||||
return NewNeg;
|
||||
}
|
||||
|
||||
/// Return true if it may be profitable to convert this (X|Y) into (X+Y).
|
||||
static bool ShouldConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
|
||||
// Don't bother to convert this up unless either the LHS is an associable add
|
||||
// or subtract or mul or if this is only used by one of the above.
|
||||
// This is only a compile-time improvement, it is not needed for correctness!
|
||||
auto isInteresting = [](Value *V) {
|
||||
for (auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul})
|
||||
if (isReassociableOp(V, Op))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
if (any_of(Or->operands(), isInteresting))
|
||||
return true;
|
||||
|
||||
Value *VB = Or->user_back();
|
||||
if (Or->hasOneUse() && isInteresting(VB))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// If we have (X|Y), and iff X and Y have no common bits set,
|
||||
/// transform this into (X+Y) to allow arithmetics reassociation.
|
||||
static BinaryOperator *ConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
|
||||
@ -2137,6 +2159,7 @@ void ReassociatePass::OptimizeInst(Instruction *I) {
|
||||
// If this is a bitwise or instruction of operands
|
||||
// with no common bits set, convert it to X+Y.
|
||||
if (I->getOpcode() == Instruction::Or &&
|
||||
ShouldConvertOrWithNoCommonBitsToAdd(I) &&
|
||||
haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1),
|
||||
I->getModule()->getDataLayout(), /*AC=*/nullptr, I,
|
||||
/*DT=*/nullptr)) {
|
||||
|
@ -6,23 +6,27 @@
|
||||
define i32 @test1(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: [[C:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
; CHECK-NEXT: [[C_PLUS_ONE:%.*]] = add i32 [[C]], 1
|
||||
; CHECK-NEXT: ret i32 [[C_PLUS_ONE]]
|
||||
;
|
||||
%c = or i32 %a, %b
|
||||
ret i32 %c
|
||||
%c.plus.one = add i32 %c, 1
|
||||
ret i32 %c.plus.one
|
||||
}
|
||||
|
||||
; But if we *do* know that operands have no common bits set,
|
||||
; we *can* convert the `or` into an `add`.
|
||||
define i32 @test2(i32 %x) {
|
||||
define i32 @test2(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: [[X_NUMLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[RNG0:!range !.*]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[X_NUMLZ]], -32
|
||||
; CHECK-NEXT: ret i32 [[RES]]
|
||||
; CHECK-NEXT: [[RES_PLUS_ONE:%.*]] = add i32 [[RES]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[RES_PLUS_ONE]]
|
||||
;
|
||||
%x.numlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true), !range !0
|
||||
%res = or i32 %x.numlz, -32
|
||||
ret i32 %res
|
||||
%res.plus.one = add i32 %res, %y
|
||||
ret i32 %res.plus.one
|
||||
}
|
||||
|
||||
; And that allows reassociation in general.
|
||||
|
Loading…
Reference in New Issue
Block a user