[InstCombine] simplify masked load intrinsics with all ones or zeros masks
A masked load with a zero mask means there's no load.
A masked load with an allOnes mask means it's a normal vector load.
Differential Revision: http://reviews.llvm.org/D16691
llvm-svn: 259369
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2661e57..ede5aeb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -753,6 +753,26 @@
return nullptr;
}
+static Value *simplifyMaskedLoad(const IntrinsicInst &II,
+ InstCombiner::BuilderTy &Builder) {
+ auto *ConstMask = dyn_cast<Constant>(II.getArgOperand(2));
+ if (!ConstMask)
+ return nullptr;
+
+ // If the mask is all zeros, the "passthru" argument is the result.
+ if (ConstMask->isNullValue())
+ return II.getArgOperand(3);
+
+ // If the mask is all ones, this is a plain vector load of the 1st argument.
+ if (ConstMask->isAllOnesValue()) {
+ Value *LoadPtr = II.getArgOperand(0);
+ unsigned Alignment = cast<ConstantInt>(II.getArgOperand(1))->getZExtValue();
+ return Builder.CreateAlignedLoad(LoadPtr, Alignment, "unmaskedload");
+ }
+
+ return nullptr;
+}
+
/// CallInst simplification. This mostly only handles folding of intrinsic
/// instructions. For normal calls, it allows visitCallSite to do the heavy
/// lifting.
@@ -877,6 +897,16 @@
break;
}
+ case Intrinsic::masked_load:
+ if (Value *SimplifiedMaskedOp = simplifyMaskedLoad(*II, *Builder))
+ return ReplaceInstUsesWith(CI, SimplifiedMaskedOp);
+ break;
+
+ // TODO: Handle the other masked ops.
+ // case Intrinsic::masked_store:
+ // case Intrinsic::masked_gather:
+ // case Intrinsic::masked_scatter:
+
case Intrinsic::powi:
if (ConstantInt *Power = dyn_cast<ConstantInt>(II->getArgOperand(1))) {
// powi(x, 0) -> 1.0