Skip to content

Commit 93f3d7f

Browse files
committed
[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`.
1 parent 85ff270 commit 93f3d7f

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

llvm/lib/Transforms/Scalar/Reassociate.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,28 @@ static Value *NegateValue(Value *V, Instruction *BI,
920920
return NewNeg;
921921
}
922922

923+
/// Return true if it may be profitable to convert this (X|Y) into (X+Y).
924+
static bool ShouldConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
925+
// Don't bother to convert this up unless either the LHS is an associable add
926+
// or subtract or mul or if this is only used by one of the above.
927+
// This is only a compile-time improvement, it is not needed for correctness!
928+
auto isInteresting = [](Value *V) {
929+
for (auto Op : {Instruction::Add, Instruction::Sub, Instruction::Mul})
930+
if (isReassociableOp(V, Op))
931+
return true;
932+
return false;
933+
};
934+
935+
if (any_of(Or->operands(), isInteresting))
936+
return true;
937+
938+
Value *VB = Or->user_back();
939+
if (Or->hasOneUse() && isInteresting(VB))
940+
return true;
941+
942+
return false;
943+
}
944+
923945
/// If we have (X|Y), and iff X and Y have no common bits set,
924946
/// transform this into (X+Y) to allow arithmetics reassociation.
925947
static BinaryOperator *ConvertOrWithNoCommonBitsToAdd(Instruction *Or) {
@@ -2137,6 +2159,7 @@ void ReassociatePass::OptimizeInst(Instruction *I) {
21372159
// If this is a bitwise or instruction of operands
21382160
// with no common bits set, convert it to X+Y.
21392161
if (I->getOpcode() == Instruction::Or &&
2162+
ShouldConvertOrWithNoCommonBitsToAdd(I) &&
21402163
haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1),
21412164
I->getModule()->getDataLayout(), /*AC=*/nullptr, I,
21422165
/*DT=*/nullptr)) {

llvm/test/Transforms/Reassociate/add-like-or.ll

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,27 @@
66
define i32 @test1(i32 %a, i32 %b) {
77
; CHECK-LABEL: @test1(
88
; CHECK-NEXT: [[C:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
9-
; CHECK-NEXT: ret i32 [[C]]
9+
; CHECK-NEXT: [[C_PLUS_ONE:%.*]] = add i32 [[C]], 1
10+
; CHECK-NEXT: ret i32 [[C_PLUS_ONE]]
1011
;
1112
%c = or i32 %a, %b
12-
ret i32 %c
13+
%c.plus.one = add i32 %c, 1
14+
ret i32 %c.plus.one
1315
}
1416

1517
; But if we *do* know that operands have no common bits set,
1618
; we *can* convert the `or` into an `add`.
17-
define i32 @test2(i32 %x) {
19+
define i32 @test2(i32 %x, i32 %y) {
1820
; CHECK-LABEL: @test2(
1921
; CHECK-NEXT: [[X_NUMLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[RNG0:!range !.*]]
2022
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[X_NUMLZ]], -32
21-
; CHECK-NEXT: ret i32 [[RES]]
23+
; CHECK-NEXT: [[RES_PLUS_ONE:%.*]] = add i32 [[RES]], [[Y:%.*]]
24+
; CHECK-NEXT: ret i32 [[RES_PLUS_ONE]]
2225
;
2326
%x.numlz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true), !range !0
2427
%res = or i32 %x.numlz, -32
25-
ret i32 %res
28+
%res.plus.one = add i32 %res, %y
29+
ret i32 %res.plus.one
2630
}
2731

2832
; And that allows reassociation in general.

0 commit comments

Comments
 (0)