mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
simplify a transformation by making it more general.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83792 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
61488a3310
commit
0036e3a469
@ -2783,39 +2783,21 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
||||
// we know the bool is either zero or one, so this is a 'masking' multiply.
|
||||
// See if we can simplify things based on how the boolean was originally
|
||||
// formed.
|
||||
CastInst *BoolCast = 0;
|
||||
if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
|
||||
if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
|
||||
BoolCast = CI;
|
||||
if (!BoolCast)
|
||||
if (ZExtInst *CI = dyn_cast<ZExtInst>(I.getOperand(1)))
|
||||
{
|
||||
Value *BoolCast = 0, *OtherOp = 0;
|
||||
if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
|
||||
if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
|
||||
BoolCast = CI;
|
||||
if (BoolCast) {
|
||||
if (ICmpInst *SCI = dyn_cast<ICmpInst>(BoolCast->getOperand(0))) {
|
||||
Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
|
||||
const Type *SCOpTy = SCIOp0->getType();
|
||||
bool TIS = false;
|
||||
|
||||
// If the icmp is true iff the sign bit of X is set, then convert this
|
||||
// multiply into a shift/and combination.
|
||||
if (isa<ConstantInt>(SCIOp1) &&
|
||||
isSignBitCheck(SCI->getPredicate(), cast<ConstantInt>(SCIOp1), TIS) &&
|
||||
TIS) {
|
||||
// Shift the X value right to turn it into "all signbits".
|
||||
Constant *Amt = ConstantInt::get(SCIOp0->getType(),
|
||||
SCOpTy->getPrimitiveSizeInBits()-1);
|
||||
Value *V = Builder->CreateAShr(SCIOp0, Amt,
|
||||
BoolCast->getOperand(0)->getName()+".mask");
|
||||
|
||||
// If the multiply type is not the same as the source type, sign extend
|
||||
// or truncate to the multiply type.
|
||||
if (I.getType() != V->getType())
|
||||
V = Builder->CreateIntCast(V, I.getType(), true);
|
||||
|
||||
Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0;
|
||||
return BinaryOperator::CreateAnd(V, OtherOp);
|
||||
}
|
||||
BoolCast = CI, OtherOp = I.getOperand(1);
|
||||
if (!BoolCast)
|
||||
if (ZExtInst *CI = dyn_cast<ZExtInst>(I.getOperand(1)))
|
||||
if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
|
||||
BoolCast = CI, OtherOp = Op0;
|
||||
|
||||
if (BoolCast) {
|
||||
// X * Y (where Y is 0 or 1) -> X & (0-Y)
|
||||
Value *V = Builder->CreateSub(Constant::getNullValue(I.getType()),
|
||||
BoolCast, "tmp");
|
||||
return BinaryOperator::CreateAnd(V, OtherOp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,4 +33,12 @@ define <2 x i1> @test5(<2 x i64> %x) {
|
||||
entry:
|
||||
%V = icmp eq <2 x i64> %x, undef
|
||||
ret <2 x i1> %V
|
||||
}
|
||||
}
|
||||
|
||||
define i32 @test6(i32 %a, i32 %b) {
|
||||
%c = icmp sle i32 %a, -1
|
||||
%d = zext i1 %c to i32
|
||||
%e = sub i32 0, %d
|
||||
%f = and i32 %e, %b
|
||||
ret i32 %f
|
||||
}
|
||||
|
@ -96,3 +96,14 @@ entry:
|
||||
%m = mul i32 %shl, %A
|
||||
ret i32 %m
|
||||
}
|
||||
|
||||
; X * Y (when Y is 0 or 1) --> x & (0-Y)
|
||||
define i32 @test16(i32 %b, i1 %c) {
|
||||
%d = zext i1 %c to i32 ; <i32> [#uses=1]
|
||||
; e = b & (a >> 31)
|
||||
%e = mul i32 %d, %b ; <i32> [#uses=1]
|
||||
ret i32 %e
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user