[llvm-commits] SHR Patch (Updated) #3/3 instcombine part
Chris Lattner
clattner at apple.com
Thu Nov 2 21:42:31 PST 2006
On Nov 2, 2006, at 3:33 PM, Reid Spencer wrote:
> Here are the SHR patches updated for recent changes on the HEAD. These
> replace the previous submission on Tuesday. If you're reviewing
> the SHR
> patches, please use this version now.
>
> ***NOTE: This is for review only, please don't commit any of this.
@@ -1143,52 +1175,40 @@ bool InstCombiner::SimplifyDemandedBits(
...
+ // If the input sign bit is known to be zero, or if none of
the top bits
+ // are demanded, turn this into an unsigned shift right.
+ if ((KnownZero & SignBit) || (HighBits & ~DemandedMask) ==
HighBits) {
+ // Convert the input to unsigned.
+ Value *NewVal = InsertCastBefore(I->getOperand(0),
+ I->getType()->getUnsignedVersion(), *I);
+ // Perform the unsigned shift right.
+ NewVal = new ShiftInst(Instruction::LShr, NewVal, SA, I-
>getName());
+ InsertNewInstBefore(cast<Instruction>(NewVal), *I);
+ // Then cast that to the destination type.
+ NewVal = new CastInst(NewVal, I->getType(), I->getName());
+ InsertNewInstBefore(cast<Instruction>(NewVal), *I);
+ return UpdateValueUsesWith(I, NewVal);
No need for the casts: just replace the single instruction with an lshr.
@@ -1897,33 +1917,50 @@ Instruction *InstCombiner::visitSub(Bina
// -((uint)X >> 31) -> ((int)X >> 31)
// -((int)X >> 31) -> ((uint)X >> 31)
if (C->isNullValue()) {
Value *NoopCastedRHS = RemoveNoopCast(Op1);
if (ShiftInst *SI = dyn_cast<ShiftInst>(NoopCastedRHS))
- if (SI->getOpcode() == Instruction::Shr)
+ if (SI->getOpcode() == Instruction::LShr) {
if (ConstantInt *CU = dyn_cast<ConstantInt>(SI->getOperand
(1))) {
- const Type *NewTy;
- if (SI->getType()->isSigned())
- NewTy = SI->getType()->getUnsignedVersion();
- else
- NewTy = SI->getType()->getSignedVersion();
+ const Type *NewTy = SI->getType()->getSignedVersion();
// Check to see if we are shifting out everything but
the sign bit.
if (CU->getZExtValue() ==
SI->getType()->getPrimitiveSizeInBits()-1) {
// Ok, the transformation is safe. Insert a cast of
the incoming
// value, then the new shift, then the new cast.
Value *InV = InsertCastBefore(SI->getOperand(0),
NewTy, I);
- Instruction *NewShift = new ShiftInst
(Instruction::Shr, InV,
+ Instruction *NewShift = new ShiftInst
(Instruction::AShr, InV,
CU, SI->getName
());
if (NewShift->getType() == I.getType())
return NewShift;
else {
InsertNewInstBefore(NewShift, I);
return new CastInst(NewShift, I.getType());
}
}
}
+ }
+ else if (SI->getOpcode() == Instruction::AShr) {
+ if (ConstantInt *CU = dyn_cast<ConstantInt>(SI->getOperand
(1))) {
+ const Type *NewTy = SI->getType()->getUnsignedVersion();
+ // Check to see if we are shifting out everything but
the sign bit.
+ if (CU->getZExtValue() ==
+ SI->getType()->getPrimitiveSizeInBits()-1) {
+ // Ok, the transformation is safe. Insert a cast of
the incoming
+ // value, then the new shift, then the new cast.
+ Value *InV = InsertCastBefore(SI->getOperand(0),
NewTy, I);
+ Instruction *NewShift = new ShiftInst
(Instruction::LShr, InV,
+ CU, SI->getName());
+ if (NewShift->getType() == I.getType())
+ return NewShift;
+ else {
+ InsertNewInstBefore(NewShift, I);
+ return new CastInst(NewShift, I.getType());
+ }
+ }
+ }
+ }
*** Likewise here, your transformation is fine, but please eliminate
the cast insertion.
@@ -2292,11 +2329,11 @@ Instruction *InstCombiner::visitUDiv(Bin
N = InsertCastBefore(N, NTy, I);
}
Constant *C2V = ConstantInt::get(NTy, C2);
N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V,
"tmp"), I);
}
- Instruction* Result = new ShiftInst(Instruction::Shr, Op0, N);
+ Instruction* Result = new ShiftInst(Instruction::LShr, Op0, N);
if (!isSigned)
return Result;
InsertNewInstBefore(Result, I);
return new CastInst(Result, NTy->getSignedVersion(),
I.getName());
}
This hunk should be more aggressive, to eliminate cast insertion.
I'd like to see something like this (this is a quick hack, please
review it for correctness):
// If the setcc 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->getOpcode(), SCIOp0, cast<ConstantInt>
(SCIOp1))) {
// Shift the X value right to turn it into "all signbits".
Constant *Amt = ConstantInt::get(Type::UByteTy,
SCOpTy-
>getPrimitiveSizeInBits()-1);
Value *V =
InsertNewInstBefore(new ShiftInst(Instruction::LShr,
SCIOp0, Amt,
BoolCast->getOperand(0)-
>getName()+
".mask"), I);
// 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()) {
if (V->getType()->isUnsigned())
V = InsertCastBefore(V, V->getType()->getSignedVersion
(), I);
V = InsertCastBefore(V, I.getType(), I);
}
@@ -2320,17 +2357,17 @@ Instruction *InstCombiner::visitUDiv(Bin
if (isSigned)
X = InsertCastBefore(X, X->getType()-
>getUnsignedVersion(), I);
// Construct the "on true" case of the select
Constant *TC = ConstantInt::get(Type::UByteTy, TSA);
Instruction *TSI =
- new ShiftInst(Instruction::Shr, X, TC, SI->getName()
+".t");
+ new ShiftInst(Instruction::LShr, X, TC, SI->getName()
+".t");
TSI = InsertNewInstBefore(TSI, I);
Likewise.
It looks like there are several other places (that I didn't list)
where you could more aggressively eliminate casts. Please tackle
these, then resend the patch for review.
Thanks,
-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20061102/bd55ff6b/attachment.html>
More information about the llvm-commits
mailing list