[InstCombine] Support pulling left shifts through a subtract with constant LHS
We already support pulling through an add with constant RHS. We can do the same for subtract. Differential Revision: https://reviews.llvm.org/D36443 llvm-svn: 310407
This commit is contained in:
parent
181dfe4c92
commit
364359e4fc
|
@ -510,6 +510,20 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1,
|
|||
NewRHS);
|
||||
}
|
||||
}
|
||||
|
||||
// If the operand is a subtract with a constant LHS, and the shift
|
||||
// is the only use, we can pull it out of the shift.
|
||||
// This folds (shl (sub C1, X), C2) -> (sub (C1 << C2), (shl X, C2))
|
||||
if (isLeftShift && Op0BO->getOpcode() == Instruction::Sub &&
|
||||
match(Op0BO->getOperand(0), m_APInt(Op0C))) {
|
||||
Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
|
||||
cast<Constant>(Op0BO->getOperand(0)), Op1);
|
||||
|
||||
Value *NewShift = Builder.CreateShl(Op0BO->getOperand(1), Op1);
|
||||
NewShift->takeName(Op0BO);
|
||||
|
||||
return BinaryOperator::CreateSub(NewRHS, NewShift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1070,3 +1070,47 @@ define i64 @test61([100 x [100 x i8]]* %foo, i64 %i, i64 %j) {
|
|||
store i8* %gep2, i8** @dummy_global2
|
||||
ret i64 %sub
|
||||
}
|
||||
|
||||
define i32 @test62(i32 %A) {
|
||||
; CHECK-LABEL: @test62(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[C:%.*]] = sub i32 2, [[B]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%B = sub i32 1, %A
|
||||
%C = shl i32 %B, 1
|
||||
ret i32 %C
|
||||
}
|
||||
|
||||
define <2 x i32> @test62vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test62vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> <i32 2, i32 2>, [[B]]
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%B = sub <2 x i32> <i32 1, i32 1>, %A
|
||||
%C = shl <2 x i32> %B, <i32 1, i32 1>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
||||
define i32 @test63(i32 %A) {
|
||||
; CHECK-LABEL: @test63(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1
|
||||
; CHECK-NEXT: ret i32 [[B]]
|
||||
;
|
||||
%B = sub i32 1, %A
|
||||
%C = shl i32 %B, 1
|
||||
%D = sub i32 2, %C
|
||||
ret i32 %D
|
||||
}
|
||||
|
||||
define <2 x i32> @test63vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @test63vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: ret <2 x i32> [[B]]
|
||||
;
|
||||
%B = sub <2 x i32> <i32 1, i32 1>, %A
|
||||
%C = shl <2 x i32> %B, <i32 1, i32 1>
|
||||
%D = sub <2 x i32> <i32 2, i32 2>, %C
|
||||
ret <2 x i32> %D
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue