summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/BDCE.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar/BDCE.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/BDCE.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index 0fa38fa80b178..767c7656dcfac 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -9,7 +9,8 @@
// This file implements the Bit-Tracking Dead Code Elimination pass. Some
// instructions (shifts, some ands, ors, etc.) kill some of their input bits.
// We track these dead bits and remove instructions that compute only these
-// dead bits.
+// dead bits. We also simplify sext that generates unused extension bits,
+// converting it to a zext.
//
//===----------------------------------------------------------------------===//
@@ -19,6 +20,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
@@ -33,6 +35,8 @@ using namespace llvm;
STATISTIC(NumRemoved, "Number of instructions removed (unused)");
STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)");
+STATISTIC(NumSExt2ZExt,
+ "Number of sign extension instructions converted to zero extension");
/// If an instruction is trivialized (dead), then the chain of users of that
/// instruction may need to be cleared of assumptions that can no longer be
@@ -102,13 +106,31 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) {
(I.getType()->isIntOrIntVectorTy() &&
DB.getDemandedBits(&I).isNullValue() &&
wouldInstructionBeTriviallyDead(&I))) {
- salvageDebugInfoOrMarkUndef(I);
+ salvageDebugInfo(I);
Worklist.push_back(&I);
I.dropAllReferences();
Changed = true;
continue;
}
+ // Convert SExt into ZExt if none of the extension bits is required
+ if (SExtInst *SE = dyn_cast<SExtInst>(&I)) {
+ APInt Demanded = DB.getDemandedBits(SE);
+ const uint32_t SrcBitSize = SE->getSrcTy()->getScalarSizeInBits();
+ auto *const DstTy = SE->getDestTy();
+ const uint32_t DestBitSize = DstTy->getScalarSizeInBits();
+ if (Demanded.countLeadingZeros() >= (DestBitSize - SrcBitSize)) {
+ clearAssumptionsOfUsers(SE, DB);
+ IRBuilder<> Builder(SE);
+ I.replaceAllUsesWith(
+ Builder.CreateZExt(SE->getOperand(0), DstTy, SE->getName()));
+ Worklist.push_back(SE);
+ Changed = true;
+ NumSExt2ZExt++;
+ continue;
+ }
+ }
+
for (Use &U : I.operands()) {
// DemandedBits only detects dead integer uses.
if (!U->getType()->isIntOrIntVectorTy())