Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LIR][SCEVExpander] Restore original flags when aborting transform #82362

Merged
merged 2 commits into from
Feb 21, 2024

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Feb 20, 2024

SCEVExpanderCleaner will currently remove instructions created by SCEVExpander, but not restore poison generating flags that it may have dropped. As such, running LIR can currently spuriously drop flags without performing any transforms.

Fix this by keeping track of original instruction flags in SCEVExpander.

Fixes #82337.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 20, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

SCEVExpanderCleaner will currently remove instructions created by SCEVExpander, but not restore poison generating flags that it may have dropped. As such, running LIR can currently spuriously drop flags without performing any transforms.

Fix this by keeping track of original instruction flags in SCEVExpander.

Fixes #82337.


Full diff: https://github.com/llvm/llvm-project/pull/82362.diff

3 Files Affected:

  • (modified) llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h (+20)
  • (modified) llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp (+42)
  • (modified) llvm/test/Transforms/LoopIdiom/pr82337.ll (+3-3)
diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index 035705b7f4b78b..955e6d967088ac 100644
--- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -41,6 +41,17 @@ struct SCEVOperand {
   const SCEV* S;
 };
 
+struct PoisonFlags {
+  unsigned NUW : 1;
+  unsigned NSW : 1;
+  unsigned Exact : 1;
+  unsigned Disjoint : 1;
+  unsigned NNeg : 1;
+
+  PoisonFlags(const Instruction *I);
+  void apply(Instruction *I);
+};
+
 /// This class uses information about analyze scalars to rewrite expressions
 /// in canonical form.
 ///
@@ -48,6 +59,8 @@ struct SCEVOperand {
 /// and destroy it when finished to allow the release of the associated
 /// memory.
 class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
+  friend class SCEVExpanderCleaner;
+
   ScalarEvolution &SE;
   const DataLayout &DL;
 
@@ -70,6 +83,10 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
   /// InsertedValues/InsertedPostIncValues.
   SmallPtrSet<Value *, 16> ReusedValues;
 
+  /// Original flags of instructions for which they were modified. Used
+  /// by SCEVExpanderCleaner to undo changes.
+  DenseMap<AssertingVH<Instruction>, PoisonFlags> OrigFlags;
+
   // The induction variables generated.
   SmallVector<WeakVH, 2> InsertedIVs;
 
@@ -188,6 +205,7 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
     InsertedValues.clear();
     InsertedPostIncValues.clear();
     ReusedValues.clear();
+    OrigFlags.clear();
     ChainedPhis.clear();
     InsertedIVs.clear();
   }
@@ -483,6 +501,8 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
 
   void rememberInstruction(Value *I);
 
+  void rememberFlags(Instruction *I);
+
   bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
 
   bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 3a28909473d95f..2e6e5c310faab7 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -43,6 +43,37 @@ cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
 
 using namespace PatternMatch;
 
+PoisonFlags::PoisonFlags(const Instruction *I) {
+  NUW = false;
+  NSW = false;
+  Exact = false;
+  Disjoint = false;
+  NNeg = false;
+  if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) {
+    NUW = OBO->hasNoUnsignedWrap();
+    NSW = OBO->hasNoUnsignedWrap();
+  }
+  if (auto *PEO = dyn_cast<PossiblyExactOperator>(I))
+    Exact = PEO->isExact();
+  if (auto *PDI = dyn_cast<PossiblyDisjointInst>(I))
+    Disjoint = PDI->isDisjoint();
+  if (auto *PNI = dyn_cast<PossiblyNonNegInst>(I))
+    NNeg = PNI->hasNonNeg();
+}
+
+void PoisonFlags::apply(Instruction *I) {
+  if (isa<OverflowingBinaryOperator>(I)) {
+    I->setHasNoUnsignedWrap(NUW);
+    I->setHasNoUnsignedWrap(NSW);
+  }
+  if (isa<PossiblyExactOperator>(I))
+    I->setIsExact(Exact);
+  if (auto *PDI = dyn_cast<PossiblyDisjointInst>(I))
+    PDI->setIsDisjoint(Disjoint);
+  if (auto *PNI = dyn_cast<PossiblyNonNegInst>(I))
+    PNI->setNonNeg(NNeg);
+}
+
 /// ReuseOrCreateCast - Arrange for there to be a cast of V to Ty at IP,
 /// reusing an existing cast if a suitable one (= dominating IP) exists, or
 /// creating a new one.
@@ -724,6 +755,7 @@ bool SCEVExpander::hoistIVInc(Instruction *IncV, Instruction *InsertPos,
   auto FixupPoisonFlags = [this](Instruction *I) {
     // Drop flags that are potentially inferred from old context and infer flags
     // in new context.
+    rememberFlags(I);
     I->dropPoisonGeneratingFlags();
     if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
       if (auto Flags = SE.getStrengthenedNoWrapFlagsFromBinOp(OBO)) {
@@ -1472,6 +1504,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
     V = fixupLCSSAFormFor(V);
   } else {
     for (Instruction *I : DropPoisonGeneratingInsts) {
+      rememberFlags(I);
       I->dropPoisonGeneratingFlagsAndMetadata();
       // See if we can re-infer from first principles any of the flags we just
       // dropped.
@@ -1512,6 +1545,11 @@ void SCEVExpander::rememberInstruction(Value *I) {
   DoInsert(I);
 }
 
+void SCEVExpander::rememberFlags(Instruction *I) {
+  // If we already have flags for the instruction, keep the existing ones.
+  OrigFlags.try_emplace(I, PoisonFlags(I));
+}
+
 void SCEVExpander::replaceCongruentIVInc(
     PHINode *&Phi, PHINode *&OrigPhi, Loop *L, const DominatorTree *DT,
     SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
@@ -2309,6 +2347,10 @@ void SCEVExpanderCleaner::cleanup() {
   if (ResultUsed)
     return;
 
+  // Restore original poison flags.
+  for (auto [I, Flags] : Expander.OrigFlags)
+    Flags.apply(I);
+
   auto InsertedInstructions = Expander.getAllInsertedInstructions();
 #ifndef NDEBUG
   SmallPtrSet<Instruction *, 8> InsertedSet(InsertedInstructions.begin(),
diff --git a/llvm/test/Transforms/LoopIdiom/pr82337.ll b/llvm/test/Transforms/LoopIdiom/pr82337.ll
index e8a6e1704f7c17..da9eb14af3f0a4 100644
--- a/llvm/test/Transforms/LoopIdiom/pr82337.ll
+++ b/llvm/test/Transforms/LoopIdiom/pr82337.ll
@@ -1,15 +1,15 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
 ; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s
 
-; FIXME: The poison flags should be preserved, as no transform takes place.
+; The poison flags should be preserved, as no transform takes place.
 define void @test(ptr %p.end, ptr %p.start) {
 ; CHECK-LABEL: define void @test(
 ; CHECK-SAME: ptr [[P_END:%.*]], ptr [[P_START:%.*]]) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[P_END_INT:%.*]] = ptrtoint ptr [[P_END]] to i64
 ; CHECK-NEXT:    [[P_START_INT:%.*]] = ptrtoint ptr [[P_START]] to i64
-; CHECK-NEXT:    [[DIST:%.*]] = sub i64 [[P_END_INT]], [[P_START_INT]]
-; CHECK-NEXT:    [[LEN:%.*]] = lshr i64 [[DIST]], 5
+; CHECK-NEXT:    [[DIST:%.*]] = sub nuw i64 [[P_END_INT]], [[P_START_INT]]
+; CHECK-NEXT:    [[LEN:%.*]] = lshr exact i64 [[DIST]], 5
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P_END]], [[P_START]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[PREHEADER:%.*]]
 ; CHECK:       preheader:

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

NNeg = false;
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) {
NUW = OBO->hasNoUnsignedWrap();
NSW = OBO->hasNoUnsignedWrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be hasNoSignedWrap? Same as below when setting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! Thanks for catching it.

SCEVExpanderCleaner will currently remove instructions created
by SCEVExpander, but not restore poison generating flags that it
may have dropped. As such, running LIR can currently spuriously
drop flags without performing any transforms.

Fix this by keeping track of original instruction flags in
SCEVExpander.

Fixes llvm#82337.
@nikic nikic merged commit 07292b7 into llvm:main Feb 21, 2024
4 checks passed
@nikic nikic deleted the lir-cleanup-fix branch February 21, 2024 09:13
@nathanchance
Copy link
Member

This patch causes a crash when building the Linux kernel for RISC-V. A trivial C reproducer from cvise, I tried to create an LLVM IR reproducer but opt -O3 -disable-output does not crash for me.

struct altera_config {
  char action;
} altera_execute_astate;
char *altera_execute_p;
unsigned altera_execute_pc;
int altera_execute_args[3];
int altera_execute_arg_count, altera_execute_i;
void _printk(char *, ...);
int altera_execute() {
  struct altera_config aconf = altera_execute_astate;
  int opcode;
  if (aconf.action) {
    opcode = altera_execute_p[altera_execute_pc];
    _printk("", opcode);
    altera_execute_arg_count = opcode >> 6;
    for (altera_execute_i = 0; altera_execute_i < altera_execute_arg_count;
         ++altera_execute_i) {
      altera_execute_args[altera_execute_i] =
          altera_execute_p[altera_execute_pc];
      altera_execute_pc += 4;
    }
  }
  return 4;
}
$ clang --target=riscv64-linux-gnu -O2 -c -o /dev/null altera.i
While deleting: i64 %wide.trip.count
An asserting value handle still pointed to this value!
UNREACHABLE executed at /home/nathan/tmp/cvise.I0yyI2BCYW/src/llvm/lib/IR/Value.cpp:1247!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: clang --target=riscv64-linux-gnu -O2 -c -o /dev/null altera.i
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module 'altera.i'.
4.	Running pass 'Loop Pass Manager' on function '@altera_execute'
5.	Running pass 'Loop Strength Reduction' on basic block '%for.body'
 #0 0x0000000003232e5c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3232e5c)
 #1 0x0000000003230d68 llvm::sys::RunSignalHandlers() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3230d68)
 #2 0x00000000031b8004 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x0000ffff90cb77a0 (linux-vdso.so.1+0x7a0)
 #4 0x0000ffff90677c40 __pthread_kill_implementation (/lib64/libc.so.6+0x97c40)
 #5 0x0000ffff90625940 gsignal (/lib64/libc.so.6+0x45940)
 #6 0x0000ffff90610288 abort (/lib64/libc.so.6+0x30288)
 #7 0x00000000031be22c llvm::install_out_of_memory_new_handler() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x31be22c)
 #8 0x0000000002e007d0 llvm::ValueHandleBase::ValueIsDeleted(llvm::Value*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2e007d0)
 #9 0x0000000002e00bc8 llvm::Value::~Value() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2e00bc8)
#10 0x0000000002e008a8 llvm::Value::deleteValue() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2e008a8)
#11 0x0000000002d7b01c llvm::Instruction::eraseFromParent() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2d7b01c)
#12 0x00000000032b6f90 llvm::RecursivelyDeleteTriviallyDeadInstructions(llvm::SmallVectorImpl<llvm::WeakTrackingVH>&, llvm::TargetLibraryInfo const*, llvm::MemorySSAUpdater*, std::function<void (llvm::Value*)>) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x32b6f90)
#13 0x00000000032b67d4 llvm::RecursivelyDeleteTriviallyDeadInstructions(llvm::Value*, llvm::TargetLibraryInfo const*, llvm::MemorySSAUpdater*, std::function<void (llvm::Value*)>) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x32b67d4)
#14 0x00000000032b7760 llvm::RecursivelyDeleteDeadPHINode(llvm::PHINode*, llvm::TargetLibraryInfo const*, llvm::MemorySSAUpdater*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x32b7760)
#15 0x0000000003250720 llvm::DeleteDeadPHIs(llvm::BasicBlock*, llvm::TargetLibraryInfo const*, llvm::MemorySSAUpdater*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3250720)
#16 0x00000000030be80c ReduceLoopStrength(llvm::Loop*, llvm::IVUsers&, llvm::ScalarEvolution&, llvm::DominatorTree&, llvm::LoopInfo&, llvm::TargetTransformInfo const&, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::MemorySSA*) LoopStrengthReduce.cpp:0:0
#17 0x00000000030eae14 (anonymous namespace)::LoopStrengthReduce::runOnLoop(llvm::Loop*, llvm::LPPassManager&) LoopStrengthReduce.cpp:0:0
#18 0x000000000260d838 llvm::LPPassManager::runOnFunction(llvm::Function&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x260d838)
#19 0x0000000002dabbf0 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2dabbf0)
#20 0x0000000002db37b8 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2db37b8)
#21 0x0000000002dac540 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2dac540)
#22 0x000000000395d8ec clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x395d8ec)
#23 0x000000000397cc60 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x397cc60)
#24 0x0000000004af3440 clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x4af3440)
#25 0x0000000003cf3104 clang::FrontendAction::Execute() (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3cf3104)
#26 0x0000000003c7a404 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3c7a404)
#27 0x0000000003dbe2ac clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3dbe2ac)
#28 0x000000000208fab0 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x208fab0)
#29 0x000000000208c438 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#30 0x0000000003b33ddc void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#31 0x00000000031b7d58 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x31b7d58)
#32 0x0000000003b33580 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3b33580)
#33 0x0000000003afc66c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3afc66c)
#34 0x0000000003afc8bc clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3afc8bc)
#35 0x0000000003b15be8 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x3b15be8)
#36 0x000000000208b88c clang_main(int, char**, llvm::ToolContext const&) (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x208b88c)
#37 0x000000000209a094 main (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x209a094)
#38 0x0000ffff906109dc __libc_start_call_main (/lib64/libc.so.6+0x309dc)
#39 0x0000ffff90610abc __libc_start_main@GLIBC_2.17 (/lib64/libc.so.6+0x30abc)
#40 0x0000000002088df0 _start (/home/nathan/tmp/cvise.I0yyI2BCYW/install/llvm-bad/bin/clang-19+0x2088df0)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ClangBuiltLinux clang version 19.0.0git (https://github.com/llvm/llvm-project.git 07292b7203e31fb90d9180bfccde0d4e84be2245)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/nathan/tmp/cvise.I0yyI2BCYW/cvise/../install/llvm-bad/bin
clang: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.
# bad: [307409a8872ff27339d5d5c6a7e7777254972f34] [flang] Fix warning fix
# good: [ff4d6c64ee4269e4a9b67a4dae7e0b82ae1c3419] Fix llvm-x86_64-debian-dylib buildbot
git bisect start '307409a8872ff27339d5d5c6a7e7777254972f34' 'ff4d6c64ee4269e4a9b67a4dae7e0b82ae1c3419'
# bad: [0a518db99e0cffcdbb4cae73e27da87edbb25170] [InstallAPI] Set InstallAPI as a standalone tool instead of CC1 action (#82293)
git bisect bad 0a518db99e0cffcdbb4cae73e27da87edbb25170
# bad: [3cb4f62de0eba62edd730d0ed80fd90d2826763d] [X86] Regenerate vector tests to add missing avx512 constant broadcast comments
git bisect bad 3cb4f62de0eba62edd730d0ed80fd90d2826763d
# good: [04fbc461e0fd1c6f2b014761e9c03ca80d17b33b] [clang-format] Fix RemoveSemicolon for empty functions (#82278)
git bisect good 04fbc461e0fd1c6f2b014761e9c03ca80d17b33b
# good: [4725993f1a812c86b9ad79d229a015d0216ff550] [clang][dataflow] Correctly handle `InitListExpr` of union type. (#82348)
git bisect good 4725993f1a812c86b9ad79d229a015d0216ff550
# bad: [91f11611337dde9a8e0a5e19240f6bb4671922c6] [mlir] expose transform interpreter to Python (#82365)
git bisect bad 91f11611337dde9a8e0a5e19240f6bb4671922c6
# bad: [1ff1e823836e6ed741c69681a2af9f1c3871e8c2] [AArch64][GlobalISel] Pre-Commit Tests for Refactor BITCAST
git bisect bad 1ff1e823836e6ed741c69681a2af9f1c3871e8c2
# bad: [07292b7203e31fb90d9180bfccde0d4e84be2245] [LIR][SCEVExpander] Restore original flags when aborting transform (#82362)
git bisect bad 07292b7203e31fb90d9180bfccde0d4e84be2245
# good: [0c13a896dfc930a09e082ad83070e223cfd9a4f9] [mlir][docs] Fix broken docs (#82308)
git bisect good 0c13a896dfc930a09e082ad83070e223cfd9a4f9
# first bad commit: [07292b7203e31fb90d9180bfccde0d4e84be2245] [LIR][SCEVExpander] Restore original flags when aborting transform (#82362)

@nikic
Copy link
Contributor Author

nikic commented Feb 22, 2024

@nathanchance Thanks for the report! Here's a reduced test case:

; RUN: opt -S -passes=loop-reduce < %s
target triple = "riscv64-unknown-linux-gnu"

define void @test(ptr %p, i8 %arg, i32 %start) {
entry:
  %conv = zext i8 %arg to i32
  %shr = lshr i32 %conv, 1
  %wide.trip.count = zext nneg i32 %shr to i64
  br label %for.body

for.body:
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %add810 = phi i32 [ %start, %entry ], [ %add, %for.body ]
  %idxprom2 = zext i32 %add810 to i64
  %arrayidx3 = getelementptr i8, ptr %p, i64 %idxprom2
  %v = load i8, ptr %arrayidx3, align 1
  %add = add i32 %add810, 1
  %indvars.iv.next = add i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv, %wide.trip.count
  br i1 %exitcond.not, label %exit, label %for.body

exit:
  ret void
}

nikic added a commit that referenced this pull request Feb 22, 2024
To avoid an assertion failure when an AssertingVH is removed,
as reported in:
#82362 (comment)

Also remove an unnecessary use of SCEVExpanderCleaner.
@nikic
Copy link
Contributor Author

nikic commented Feb 22, 2024

The issue should be fixed by 7276352.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[LoopIdiomRecognize] Poison flags stripped even though no transform performed
5 participants