@@ -2135,6 +2135,58 @@ Value *llvm::addRuntimeChecks(
21352135 return MemoryRuntimeCheck;
21362136}
21372137
2138+ Value *llvm::addSafeEltsRuntimeChecks (Instruction *Loc,
2139+ ArrayRef<PointerDiffInfo> Checks,
2140+ SCEVExpander &Expander, ElementCount VF) {
2141+ IRBuilder ChkBuilder (Loc->getContext (),
2142+ InstSimplifyFolder (Loc->getDataLayout ()));
2143+ ChkBuilder.SetInsertPoint (Loc);
2144+ Value *MemoryRuntimeCheck = nullptr ;
2145+
2146+ // Map to keep track of created compares, The key is the pair of operands for
2147+ // the compare, to allow detecting and re-using redundant compares.
2148+ DenseMap<std::pair<Value *, Value *>, Value *> SeenCompares;
2149+ Value *AliasLaneMask = nullptr ;
2150+ for (const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze,
2151+ WriteAfterRead] : Checks) {
2152+ Type *Ty = SinkStart->getType ();
2153+ Value *Sink = Expander.expandCodeFor (SinkStart, Ty, Loc);
2154+ Value *Src = Expander.expandCodeFor (SrcStart, Ty, Loc);
2155+ if (SeenCompares.lookup ({Sink, Src}))
2156+ continue ;
2157+
2158+ unsigned IntOpc = WriteAfterRead ? Intrinsic::loop_dependence_war_mask
2159+ : Intrinsic::loop_dependence_raw_mask;
2160+ Value *SourceAsPtr = ChkBuilder.CreateCast (Instruction::IntToPtr, Src,
2161+ ChkBuilder.getPtrTy ());
2162+ Value *SinkAsPtr = ChkBuilder.CreateCast (Instruction::IntToPtr, Sink,
2163+ ChkBuilder.getPtrTy ());
2164+ Value *M = ChkBuilder.CreateIntrinsic (
2165+ IntOpc, {VectorType::get (ChkBuilder.getInt1Ty (), VF)},
2166+ {SourceAsPtr, SinkAsPtr, ChkBuilder.getInt64 (AccessSize)}, nullptr ,
2167+ " alias.lane.mask" );
2168+ SeenCompares.insert ({{Sink, Src}, M});
2169+ if (AliasLaneMask)
2170+ M = ChkBuilder.CreateAnd (AliasLaneMask, M);
2171+ else
2172+ AliasLaneMask = M;
2173+ }
2174+ assert (AliasLaneMask && " Expected an alias lane mask to have been created." );
2175+ auto *VecVT = VectorType::get (ChkBuilder.getInt1Ty (), VF);
2176+ // Extend to an i8 since i1 is too small to add with
2177+ Value *PopCount = ChkBuilder.CreateCast (
2178+ Instruction::ZExt, AliasLaneMask,
2179+ VectorType::get (ChkBuilder.getInt8Ty (), VecVT->getElementCount ()));
2180+
2181+ PopCount =
2182+ ChkBuilder.CreateUnaryIntrinsic (Intrinsic::vector_reduce_add, PopCount);
2183+ PopCount = ChkBuilder.CreateCast (Instruction::ZExt, PopCount,
2184+ ChkBuilder.getInt64Ty ());
2185+ MemoryRuntimeCheck = ChkBuilder.CreateICmpUGT (
2186+ PopCount, ConstantInt::get (ChkBuilder.getInt64Ty (), 0 ));
2187+ return MemoryRuntimeCheck;
2188+ }
2189+
21382190Value *llvm::addDiffRuntimeChecks (
21392191 Instruction *Loc, ArrayRef<PointerDiffInfo> Checks, SCEVExpander &Expander,
21402192 function_ref<Value *(IRBuilderBase &, unsigned )> GetVF, unsigned IC) {
@@ -2149,7 +2201,8 @@ Value *llvm::addDiffRuntimeChecks(
21492201 // Map to keep track of created compares, The key is the pair of operands for
21502202 // the compare, to allow detecting and re-using redundant compares.
21512203 DenseMap<std::pair<Value *, Value *>, Value *> SeenCompares;
2152- for (const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze] : Checks) {
2204+ for (const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze,
2205+ WriteAfterRead] : Checks) {
21532206 Type *Ty = SinkStart->getType ();
21542207 // Compute VF * IC * AccessSize.
21552208 auto *VFTimesICTimesSize =
@@ -2158,8 +2211,8 @@ Value *llvm::addDiffRuntimeChecks(
21582211 Value *Diff =
21592212 Expander.expandCodeFor (SE.getMinusSCEV (SinkStart, SrcStart), Ty, Loc);
21602213
2161- // Check if the same compare has already been created earlier. In that case,
2162- // there is no need to check it again.
2214+ // Check if the same compare has already been created earlier. In that
2215+ // case, there is no need to check it again.
21632216 Value *IsConflict = SeenCompares.lookup ({Diff, VFTimesICTimesSize});
21642217 if (IsConflict)
21652218 continue ;
0 commit comments