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

Reland [SimplifyCFG] Delete the unnecessary range check for small mask operation #70542

Merged
merged 2 commits into from
Nov 3, 2023

Conversation

vfdff
Copy link
Contributor

@vfdff vfdff commented Oct 28, 2023

Fix the compile crash when the default result is not exist for #65835

@llvmbot
Copy link
Member

llvmbot commented Oct 28, 2023

@llvm/pr-subscribers-llvm-transforms

Author: Allen (vfdff)

Changes

Fix the compile crash when the default result is not exist for #65835


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+22-2)
  • (modified) llvm/test/Transforms/SimplifyCFG/switch_mask.ll (+44-14)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 68b5b1a78a3460e..a9585d2ed963f3a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6598,9 +6598,8 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
   // If the default destination is unreachable, or if the lookup table covers
   // all values of the conditional variable, branch directly to the lookup table
   // BB. Otherwise, check that the condition is within the case range.
-  const bool DefaultIsReachable =
+  bool DefaultIsReachable =
       !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
-  const bool GeneratingCoveredLookupTable = (MaxTableSize == TableSize);
 
   // Create the BB that does the lookups.
   Module &Mod = *CommonDest->getParent()->getParent();
@@ -6631,6 +6630,27 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
 
   BranchInst *RangeCheckBranch = nullptr;
 
+  // Grow the table to cover all possible index values to avoid the range check.
+  // It will use the default result to fill in the table hole later, so make
+  // sure it exist.
+  if (UseSwitchConditionAsTableIndex && HasDefaultResults) {
+    ConstantRange CR = computeConstantRange(TableIndex, /* ForSigned */ false);
+    // Grow the table shouldn't have any size impact by checking
+    // WouldFitInRegister.
+    // TODO: Consider growing the table also when it doesn't fit in a register
+    // if no optsize is specified.
+    if (all_of(ResultTypes, [&](const auto &KV) {
+          return SwitchLookupTable::WouldFitInRegister(
+              DL, CR.getUpper().getLimitedValue(), KV.second /* ResultType */);
+        })) {
+      // The default branch is unreachable when we enlarge the lookup table.
+      // Adjust DefaultIsReachable to reuse code path.
+      TableSize = CR.getUpper().getZExtValue();
+      DefaultIsReachable = false;
+    }
+  }
+
+  const bool GeneratingCoveredLookupTable = (MaxTableSize == TableSize);
   if (!DefaultIsReachable || GeneratingCoveredLookupTable) {
     Builder.CreateBr(LookupBB);
     if (DTU)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
index 8c97a0660d07074..867fbc0c5e9b6c2 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
@@ -8,13 +8,11 @@ define i1 @switch_lookup_with_small_i1(i64 %x) {
 ; CHECK-LABEL: @switch_lookup_with_small_i1(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[AND]], 11
-; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = trunc i64 [[AND]] to i11
-; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i11 [[SWITCH_CAST]], 1
-; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i11 -1018, [[SWITCH_SHIFTAMT]]
-; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i11 [[SWITCH_DOWNSHIFT]] to i1
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false
-; CHECK-NEXT:    ret i1 [[TMP1]]
+; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = trunc i64 [[AND]] to i16
+; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i16 [[SWITCH_CAST]], 1
+; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i16 1030, [[SWITCH_SHIFTAMT]]
+; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i16 [[SWITCH_DOWNSHIFT]] to i1
+; CHECK-NEXT:    ret i1 [[SWITCH_MASKED]]
 ;
 entry:
   %and = and i64 %x, 15
@@ -37,13 +35,11 @@ define i8 @switch_lookup_with_small_i8(i64 %x) {
 ; CHECK-LABEL: @switch_lookup_with_small_i8(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[REM:%.*]] = urem i64 [[X:%.*]], 5
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[REM]], 3
-; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = trunc i64 [[REM]] to i24
-; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i24 [[SWITCH_CAST]], 8
-; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i24 460303, [[SWITCH_SHIFTAMT]]
-; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i24 [[SWITCH_DOWNSHIFT]] to i8
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[TMP0]], i8 [[SWITCH_MASKED]], i8 0
-; CHECK-NEXT:    ret i8 [[TMP1]]
+; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = trunc i64 [[REM]] to i40
+; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul nuw nsw i40 [[SWITCH_CAST]], 8
+; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i40 460303, [[SWITCH_SHIFTAMT]]
+; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i40 [[SWITCH_DOWNSHIFT]] to i8
+; CHECK-NEXT:    ret i8 [[SWITCH_MASKED]]
 ;
 entry:
   %rem = urem i64 %x, 5
@@ -107,3 +103,37 @@ lor.end:
   %0 = phi i8 [ 15, %sw.bb0 ], [ 6, %sw.bb1 ], [ 7, %sw.bb2 ], [ 0, %default ]
   ret i8 %0
 }
+
+; Negative test: The default branch is unreachable.
+define i1 @switch_lookup_with_small_i1_unreachable(i32 %x) {
+; CHECK-LABEL: @switch_lookup_with_small_i1_unreachable(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    ret i1 false
+;
+entry:
+  %and = and i32 %x, 15
+  switch i32 %and, label %default [
+  i32 4, label %phi.end
+  i32 2, label %phi.end
+  i32 10, label %phi.end
+  i32 9, label %phi.end
+  i32 1, label %sw.bb1.i
+  i32 3, label %sw.bb1.i
+  i32 5, label %sw.bb1.i
+  i32 0, label %sw.bb1.i
+  i32 6, label %sw.bb1.i
+  i32 7, label %sw.bb1.i
+  i32 8, label %sw.bb1.i
+  ]
+
+sw.bb1.i:                                     ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry
+  br label %phi.end
+
+default:                                      ; preds = %entry
+  unreachable
+
+phi.end: ; preds = %sw.bb1.i, %entry, %entry, %entry, %entry
+  %retval.0.i = phi i1 [ false, %sw.bb1.i ], [ false, %entry ], [ false, %entry ], [ false, %entry ], [ false, %entry ]
+  ret i1 false
+}

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

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

Thanks! The fix looks right to me. It would be good to have a test which covers the case where HasDefaultResults is false though.

@vfdff
Copy link
Contributor Author

vfdff commented Oct 31, 2023

Thanks! The fix looks right to me. It would be good to have a test which covers the case where HasDefaultResults is false though.

hi @zmodem, the new added switch_lookup_with_small_i1_unreachable already matched the case where HasDefaultResults is false, so I can rename it to switch_lookup_with_small_i1_default_no_results if its name is easy to confuse ? (HasDefaultResults is false before the fix, so an error is reported when DefaultResults is used to fill in table hole.)

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

@zmodem
Copy link
Collaborator

zmodem commented Oct 31, 2023

Thanks! The fix looks right to me. It would be good to have a test which covers the case where HasDefaultResults is false though.

hi @zmodem, the new added switch_lookup_with_small_i1_unreachable already matched the case where HasDefaultResults is false, so I can rename it to switch_lookup_with_small_i1_default_no_results if its name is easy to confuse ? (HasDefaultResults is false before the fix, so an error is reported when DefaultResults is used to fill in table hole.)

I think I've also confused myself about HasDefaultResults and DefaultIsReachable.

!DefaultIsReachable implies !HasDefaultResults

so yes, the current test covers where we asserted before, but there are other situations where DefaultIsReachable can be false, such as when the default case does not result in a constant. I think it would be good if the test covered that too.

@vfdff
Copy link
Contributor Author

vfdff commented Nov 1, 2023

Thanks @zmodem for your suggestion, I add a new caset switch_lookup_with_small_i1_unraachable to make sure the default branch unreaachable, which list all the possible cases of switch.

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

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

I think we misunderstood each other. I meant we should have a test where the default case is reasonable, but does not yield a constant value. For example because it calls a function and feeds the return value to the phi node.

br label %phi.end

default: ; preds = %entry
unreachable
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand. The comment says the default is reachable, but here it's marked unreachable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I record it reachable because DefaultIsReachable is true for this case, and there is some case, such as i32 10 will hit the default branch. Does this not fit the usual description?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Since the default block starts with an unreachable instruction, DefaultIsReachable will be false:

const bool DefaultIsReachable =
!isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());

I was thinking of something like this, where the default doesn't yield a constant result, so we can't grow the table:

bool g(int x);

bool f(int x) {
    switch (x % 8) {
    case 0: return true;
    case 1: return false;
    case 2: return false;
    case 3: return false;
    case 4: return true;
    case 5: return false;
    case 6: return true;

    default: return g(x);
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, thanks very much for detail case, I'll update this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add switch_lookup_with_small_i1_default_nonconst for above case, thanks @zmodem

vfdff added 2 commits November 2, 2023 11:00
…tion

When the small mask value little than 64, we can eliminate the checking
for upper limit of the range by enlarge the lookup table size to the maximum
index value. (Then the final table size grows to the next pow2 value)
```
bool f(unsigned x) {
    switch (x % 8) {
        case 0: return 1;
        case 1: return 0;
        case 2: return 0;
        case 3: return 1;
        case 4: return 1;
        case 5: return 0;
        case 6: return 1;

        // This would remove the range check: case 7: return 0;
    }
    return 0;
}
```
Use WouldFitInRegister instead of fitsInLegalInteger to support
more result type beside bool.

Fixes llvm#65120
This modification will squash to the previous commit if accepted.
Seperate it just to make it more clearly to review.
Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@vfdff vfdff changed the title Reland [SimplifyCFG] Delete the unnecessary range check for small mask operation [SimplifyCFG] Delete the unnecessary range check for small mask operation Nov 3, 2023
@vfdff vfdff merged commit 7c4180a into llvm:main Nov 3, 2023
2 checks passed
@vfdff vfdff changed the title [SimplifyCFG] Delete the unnecessary range check for small mask operation Reland [SimplifyCFG] Delete the unnecessary range check for small mask operation Nov 3, 2023
@nathanchance
Copy link
Member

This change appears to cause a crash for me when building with -fsanitize=thread. A reduced LLVM IR reproducer from llvm-reduce:

; ModuleID = 'gfx_v8_0.i'
source_filename = "gfx_v8_0.i"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

@max_shader_engines = dso_local global i32 0, align 4

; Function Attrs: nounwind sanitize_thread uwtable
define dso_local void @gfx_v8_0_setup_rb() #0 {
entry:
  %num_se = alloca i32, align 4
  %tmp = alloca i32, align 4
  %__ret_warn_on = alloca i32, align 4
  call void @llvm.lifetime.start.p0(i64 4, ptr %num_se) #4
  %0 = load i32, ptr @max_shader_engines, align 4, !tbaa !5
  %tobool = icmp ne i32 %0, 0
  br i1 %tobool, label %cond.true, label %cond.false

cond.true:                                        ; preds = %entry
  %1 = load i32, ptr @max_shader_engines, align 4, !tbaa !5
  br label %cond.end

cond.false:                                       ; preds = %entry
  br label %cond.end

cond.end:                                         ; preds = %cond.false, %cond.true
  %cond = phi i32 [ %1, %cond.true ], [ 1, %cond.false ]
  store i32 %cond, ptr %tmp, align 4, !tbaa !5
  %2 = load i32, ptr %tmp, align 4, !tbaa !5
  store i32 %2, ptr %num_se, align 4, !tbaa !5
  call void @llvm.lifetime.start.p0(i64 4, ptr %__ret_warn_on) #4
  %3 = load i32, ptr %num_se, align 4, !tbaa !5
  %cmp = icmp eq i32 %3, 1
  br i1 %cmp, label %lor.end, label %lor.lhs.false

lor.lhs.false:                                    ; preds = %cond.end
  %4 = load i32, ptr %num_se, align 4, !tbaa !5
  %cmp1 = icmp eq i32 %4, 2
  br i1 %cmp1, label %lor.end, label %lor.rhs

lor.rhs:                                          ; preds = %lor.lhs.false
  %5 = load i32, ptr %num_se, align 4, !tbaa !5
  %cmp2 = icmp eq i32 %5, 4
  br label %lor.end

lor.end:                                          ; preds = %lor.rhs, %lor.lhs.false, %cond.end
  %6 = phi i1 [ true, %lor.lhs.false ], [ true, %cond.end ], [ %cmp2, %lor.rhs ]
  %lor.ext = zext i1 %6 to i32
  store i32 %lor.ext, ptr %__ret_warn_on, align 4, !tbaa !5
  %7 = load i32, ptr %__ret_warn_on, align 4, !tbaa !5
  %8 = call i1 @llvm.is.constant.i32(i32 %7)
  br i1 %8, label %if.then, label %if.else

if.then:                                          ; preds = %lor.end
  br label %if.end5

if.else:                                          ; preds = %lor.end
  %9 = load i32, ptr %__ret_warn_on, align 4, !tbaa !5
  %conv = sext i32 %9 to i64
  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 0)
  %tobool3 = icmp ne i64 %expval, 0
  br i1 %tobool3, label %if.then4, label %if.end

if.then4:                                         ; preds = %if.else
  call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() #4, !srcloc !9
  br label %if.end

if.end:                                           ; preds = %if.then4, %if.else
  br label %if.end5

if.end5:                                          ; preds = %if.end, %if.then
  call void @llvm.lifetime.end.p0(i64 4, ptr %__ret_warn_on) #4
  call void @llvm.lifetime.end.p0(i64 4, ptr %num_se) #4
  ret void
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1

; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
declare i1 @llvm.is.constant.i32(i32) #2

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
declare i64 @llvm.expect.i64(i64, i64) #3

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1

attributes #0 = { nounwind sanitize_thread uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) }
attributes #4 = { nounwind }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"ClangBuiltLinux clang version 18.0.0 (https://github.com/llvm/llvm-project 7c4180a36a905b7ed46c09df77af1b65e356f92a)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = !{i64 299}

At 7c4180a:

$ opt -O2 -disable-output reduced.ll
opt: /mnt/nvme/tmp/cvise.A8xoH9LhLH/src/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6097: (anonymous namespace)::SwitchLookupTable::SwitchLookupTable(Module &, uint64_t, ConstantInt *, const SmallVectorImpl<std::pair<ConstantInt *, Constant *>> &, Constant *, const DataLayout &, const StringRef &): Assertion `TableSize >= Values.size() && "Can't fit values in table!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: opt -O2 -disable-output reduced.ll
 #0 0x0000562678cfbb78 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4f20b78)
 #1 0x0000562678cf973e llvm::sys::RunSignalHandlers() (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4f1e73e)
 #2 0x0000562678cfc358 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007f98f65d1710 (/usr/lib/libc.so.6+0x3e710)
 #4 0x00007f98f662183c (/usr/lib/libc.so.6+0x8e83c)
 #5 0x00007f98f65d1668 gsignal (/usr/lib/libc.so.6+0x3e668)
 #6 0x00007f98f65b94b8 abort (/usr/lib/libc.so.6+0x264b8)
 #7 0x00007f98f65b93dc (/usr/lib/libc.so.6+0x263dc)
 #8 0x00007f98f65c9d26 (/usr/lib/libc.so.6+0x36d26)
 #9 0x0000562678e49bd6 SwitchToLookupTable(llvm::SwitchInst*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&, llvm::DomTreeUpdater*, llvm::DataLayout const&, llvm::TargetTransformInfo const&) SimplifyCFG.cpp:0:0
#10 0x0000562678e30f58 (anonymous namespace)::SimplifyCFGOpt::simplifySwitch(llvm::SwitchInst*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&) SimplifyCFG.cpp:0:0
#11 0x0000562678e24df2 (anonymous namespace)::SimplifyCFGOpt::run(llvm::BasicBlock*) SimplifyCFG.cpp:0:0
#12 0x0000562678e22062 llvm::simplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&, llvm::ArrayRef<llvm::WeakVH>) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x5047062)
#13 0x0000562678bfda0d iterativelySimplifyCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#14 0x0000562678bfd41c simplifyFunctionCFGImpl(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#15 0x0000562678bfc091 simplifyFunctionCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) SimplifyCFGPass.cpp:0:0
#16 0x0000562678bfbe62 llvm::SimplifyCFGPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4e20e62)
#17 0x00005626772d95ad llvm::detail::PassModel<llvm::Function, llvm::SimplifyCFGPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) BPFTargetMachine.cpp:0:0
#18 0x00005626787e8c74 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4a0dc74)
#19 0x00005626772d912d llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) BPFTargetMachine.cpp:0:0
#20 0x00005626787ecf03 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4a11f03)
#21 0x00005626772d8ecd llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) BPFTargetMachine.cpp:0:0
#22 0x00005626787e7e54 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x4a0ce54)
#23 0x0000562676d6aceb llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x2f8fceb)
#24 0x0000562676d78eea main (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x2f9deea)
#25 0x00007f98f65bacd0 (/usr/lib/libc.so.6+0x27cd0)
#26 0x00007f98f65bad8a __libc_start_main (/usr/lib/libc.so.6+0x27d8a)
#27 0x0000562676d645e5 _start (/mnt/nvme/tmp/cvise.A8xoH9LhLH/install/llvm-bad/bin/opt+0x2f895e5)

At 1021404:

$ opt -O2 -disable-output reduced.ll

Bisect log below, if there is any additional information I can provide or patches I can test, I am more than happy to do so.

# bad: [d301a2895053fb335de0ba456d8cf80855a24fd9] [OpenMP] Guard Virtual Memory Management API and Types (#70986)
# good: [7b5505b0d597eddadd5ffd4bbf80a7e8804ec809] [PowerPC] Change registers used in test due to ABI breakage. NFC. (#70758)
git bisect start 'd301a2895053fb335de0ba456d8cf80855a24fd9' '7b5505b0d597eddadd5ffd4bbf80a7e8804ec809'
# bad: [1061c0150b587c721aaddd8250d562976dbcd7d6] [libc++] Remove legacy feature suse-linux-enterprise-server-11 (#71103)
git bisect bad 1061c0150b587c721aaddd8250d562976dbcd7d6
# bad: [e9db60c05e2fb96ff40cbb1f78790abc5de9237e] Reapply [clang-repl] [test] Make an XFAIL more precise (#70991)
git bisect bad e9db60c05e2fb96ff40cbb1f78790abc5de9237e
# bad: [b5b251aac80fbcfa224b0a83efa0a12bd747fafe] [OpenMP] Add support for Solaris/x86_64 (#70593)
git bisect bad b5b251aac80fbcfa224b0a83efa0a12bd747fafe
# good: [46732e2abb34fd7a5c1d52b959d4d07f118479dd] [GISel] Remove BitVector from RegBank. Use tablegen CoverageData tables directly. NFC (#71105)
git bisect good 46732e2abb34fd7a5c1d52b959d4d07f118479dd
# bad: [65dc96c2cfa480b070c7913ac5e313c98ca96520] [RISCV] Fix wrong implication for zvknhb. (#66860)
git bisect bad 65dc96c2cfa480b070c7913ac5e313c98ca96520
# good: [1021404619724568d62f53e575b61ae84e82ca02] [GISel] Make RegBank constructor constexpr. NFC (#71109)
git bisect good 1021404619724568d62f53e575b61ae84e82ca02
# bad: [7c4180a36a905b7ed46c09df77af1b65e356f92a] Reland [SimplifyCFG] Delete the unnecessary range check for small mask operation (#70542)
git bisect bad 7c4180a36a905b7ed46c09df77af1b65e356f92a
# first bad commit: [7c4180a36a905b7ed46c09df77af1b65e356f92a] Reland [SimplifyCFG] Delete the unnecessary range check for small mask operation (#70542)

@vfdff
Copy link
Contributor Author

vfdff commented Nov 6, 2023

thanks @nathanchance for your report, and it is seems a similar issue to #71329

zmodem added a commit that referenced this pull request Nov 7, 2023
…mall mask operation (#70542)"

This caused #71329

> Fix the compile crash when the default result has no result  for
> #65835
>
> Fixes #65120
> Reviewed By: zmodem, nikic

This reverts commit 7c4180a.
@DimitryAndric
Copy link
Collaborator

FWIW this causes https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278320 :

+ clang -cc1 -triple x86_64-unknown-freebsd15.0 -emit-obj -disable-free -clear-ast-before-backend -main-file-name DynamicModel.cc -mrelocation-model static '-mframe-pointer=all' -relaxed-aliasing '-ffp-contract=on' -fno-rounding-math -mconstructor-aliases '-funwind-tables=2' -target-cpu x86-64 -tune-cpu generic '-debugger-tuning=gdb' '-fdebug-compilation-dir=/wrkdirs/share/dim/ports/science/dynare/work/dynare-5.4/preprocessor/src' '-fcoverage-compilation-dir=/wrkdirs/share/dim/ports/science/dynare/work/dynare-5.4/preprocessor/src' -sys-header-deps -D 'PACKAGE_NAME="dynare-preprocessor"' -D 'PACKAGE_TARNAME="dynare-preprocessor"' -D 'PACKAGE_VERSION="5.4"' -D 'PACKAGE_STRING="dynare-preprocessor 5.4"' -D 'PACKAGE_BUGREPORT=""' -D 'PACKAGE_URL=""' -D 'PACKAGE="dynare-preprocessor"' -D 'VERSION="5.4"' -D 'HAVE_CXX17=1' -D 'HAVE_BOOST=/**/' -D 'STDC_HEADERS=1' -D 'HAVE_SYS_TYPES_H=1' -D 'HAVE_SYS_STAT_H=1' -D 'HAVE_STDLIB_H=1' -D 'HAVE_STRING_H=1' -D 'HAVE_MEMORY_H=1' -D 'HAVE_STRINGS_H=1' -D 'HAVE_INTTYPES_H=1' -D 'HAVE_STDINT_H=1' -D 'HAVE_UNISTD_H=1' -D 'HAVE_BOOST_GRAPH_ADJACENCY_LIST_HPP=1' -D 'HAVE_BOOST_ALGORITHM_STRING_TRIM_HPP=1' -D 'HAVE_BOOST_ALGORITHM_STRING_SPLIT_HPP=1' -D 'BOOST_NO_HASH=/**/' -O2 -Wall -Wextra -Wold-style-cast -Werror -Wno-misleading-indentation -Wno-parentheses -Wno-unqualified-std-cast-call -Wno-unused-parameter -Wno-vla-cxx-extension -fdeprecated-macro -ferror-limit 19 -stack-protector 2 '-fgnuc-version=4.2.1' -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -faddrsig '-D__GCC_HAVE_DWARF2_CFI_ASM=1' -x c++ DynamicModel-49621a.cpp
Assertion failed: (idx < size()), function operator[], file /usr/src/contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h, line 304.
PLEASE submit a bug report to https://bugs.freebsd.org/submit/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: clang -cc1 -triple x86_64-unknown-freebsd15.0 -emit-obj -disable-free -clear-ast-before-backend -main-file-name DynamicModel.cc -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/wrkdirs/share/dim/ports/science/dynare/work/dynare-5.4/preprocessor/src -fcoverage-compilation-dir=/wrkdirs/share/dim/ports/science/dynare/work/dynare-5.4/preprocessor/src -sys-header-deps -D PACKAGE_NAME=\"dynare-preprocessor\" -D PACKAGE_TARNAME=\"dynare-preprocessor\" -D PACKAGE_VERSION=\"5.4\" -D "PACKAGE_STRING=\"dynare-preprocessor 5.4\"" -D PACKAGE_BUGREPORT=\"\" -D PACKAGE_URL=\"\" -D PACKAGE=\"dynare-preprocessor\" -D VERSION=\"5.4\" -D HAVE_CXX17=1 -D HAVE_BOOST=/**/ -D STDC_HEADERS=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_MEMORY_H=1 -D HAVE_STRINGS_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_UNISTD_H=1 -D HAVE_BOOST_GRAPH_ADJACENCY_LIST_HPP=1 -D HAVE_BOOST_ALGORITHM_STRING_TRIM_HPP=1 -D HAVE_BOOST_ALGORITHM_STRING_SPLIT_HPP=1 -D BOOST_NO_HASH=/**/ -O2 -Wall -Wextra -Wold-style-cast -Werror -Wno-misleading-indentation -Wno-parentheses -Wno-unqualified-std-cast-call -Wno-unused-parameter -Wno-vla-cxx-extension -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ DynamicModel-49621a.cpp
1.      <eof> parser at end of file
2.      Optimizer
 #0 0x0000000005aa5a41 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:13
 #1 0x0000000005aa3a35 llvm::sys::RunSignalHandlers() /usr/src/contrib/llvm-project/llvm/lib/Support/Signals.cpp:106:18
 #2 0x0000000005aa6042 SignalHandler(int) /usr/src/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
 #3 0x000000082b89e440 handle_signal /usr/src/lib/libthr/thread/thr_sig.c:0:3
 #4 0x000000082b89d9fb thr_sighandler /usr/src/lib/libthr/thread/thr_sig.c:244:1
 #5 0x00000008288302d3 ([vdso]+0x2d3)
 #6 0x000000082f44619a thr_kill /usr/obj/usr/src/amd64.amd64/lib/libsys/thr_kill.S:4:0
 #7 0x000000082d4cc714 _raise /usr/src/lib/libc/gen/raise.c:0:10
 #8 0x000000082d57fcc9 abort /usr/src/lib/libc/stdlib/abort.c:67:17
 #9 0x000000082d4b0091 (/lib/libc.so.7+0x9c091)
#10 0x00000000072b944a SwitchToLookupTable(llvm::SwitchInst*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&, llvm::DomTreeUpdater*, llvm::DataLayout const&, llvm::TargetTransformInfo const&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:0:0
#11 0x00000000072a02f5 (anonymous namespace)::SimplifyCFGOpt::simplifySwitch(llvm::SwitchInst*, llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:7042:7
#12 0x00000000072979e9 (anonymous namespace)::SimplifyCFGOpt::simplifyOnce(llvm::BasicBlock*) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:0:16
#13 0x0000000007295bef (anonymous namespace)::SimplifyCFGOpt::run(llvm::BasicBlock*) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:7608:13
#14 0x0000000007295bef llvm::simplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&, llvm::ArrayRef<llvm::WeakVH>) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Utils/SimplifyCFG.cpp:7619:8
#15 0x00000000071475ca iterativelySimplifyCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp:255:11
#16 0x0000000007146e4f simplifyFunctionCFGImpl(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp:273:18
#17 0x0000000007146e4f simplifyFunctionCFG(llvm::Function&, llvm::TargetTransformInfo const&, llvm::DominatorTree*, llvm::SimplifyCFGOptions const&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp:301:18
#18 0x0000000007145fce llvm::SimplifyCFGPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /usr/src/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp:363:7
#19 0x000000000590dc12 llvm::detail::PassModel<llvm::Function, llvm::SimplifyCFGPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:89:5
#20 0x00000000056befe1 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h:547:10
#21 0x000000000314f312 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:89:5
#22 0x00000000056c1832 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /usr/src/contrib/llvm-project/llvm/lib/IR/PassManager.cpp:128:23
#23 0x0000000003149992 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:89:5
#24 0x00000000056be421 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h:547:10
#25 0x00000000031462ab llvm::SmallPtrSetImplBase::isSmall() const /usr/src/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:195:33
#26 0x00000000031462ab llvm::SmallPtrSetImplBase::~SmallPtrSetImplBase() /usr/src/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:83:10
#27 0x00000000031462ab llvm::PreservedAnalyses::~PreservedAnalyses() /usr/src/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h:172:7
#28 0x00000000031462ab (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>&, std::__1::unique_ptr<llvm::ToolOutputFile, std::__1::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) /usr/src/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1101:5
#29 0x000000000313ee28 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) /usr/src/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:0:3
#30 0x000000000313ee28 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::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) /usr/src/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1328:13
#31 0x0000000003154574 std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>::reset[abi:sn180100](llvm::raw_pwrite_stream*) /usr/obj/usr/src/amd64.amd64/tmp/usr/include/c++/v1/__memory/unique_ptr.h:263:29
#32 0x0000000003154574 std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>::~unique_ptr[abi:sn180100]() /usr/obj/usr/src/amd64.amd64/tmp/usr/include/c++/v1/__memory/unique_ptr.h:236:71
#33 0x0000000003154574 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) /usr/src/contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:379:3
#34 0x0000000003aea286 std::__1::vector<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>, std::__1::allocator<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>>>::begin[abi:sn180100]() /usr/obj/usr/src/amd64.amd64/tmp/usr/include/c++/v1/vector:1369:28
#35 0x0000000003aea286 void clang::finalize<std::__1::vector<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>, std::__1::allocator<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>>>>(std::__1::vector<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>, std::__1::allocator<std::__1::unique_ptr<clang::TemplateInstantiationCallback, std::__1::default_delete<clang::TemplateInstantiationCallback>>>>&, clang::Sema const&) /usr/src/contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h:54:16
#36 0x0000000003aea286 clang::ParseAST(clang::Sema&, bool, bool) /usr/src/contrib/llvm-project/clang/lib/Parse/ParseAST.cpp:183:3
#37 0x000000000341cc7f clang::FrontendAction::Execute() /usr/src/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1073:10
#38 0x000000000334d28d llvm::Error::getPtr() const /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Error.h:276:42
#39 0x000000000334d28d llvm::Error::operator bool() /usr/src/contrib/llvm-project/llvm/include/llvm/Support/Error.h:239:16
#40 0x000000000334d28d clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /usr/src/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1057:23
#41 0x00000000034e7c1c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /usr/src/contrib/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:272:25
#42 0x0000000002729621 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /usr/src/contrib/llvm-project/clang/tools/driver/cc1_main.cpp:294:15
#43 0x00000000027389ab ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /usr/src/contrib/llvm-project/clang/tools/driver/driver.cpp:365:12
#44 0x0000000002737a97 clang_main(int, char**, llvm::ToolContext const&) /usr/src/contrib/llvm-project/clang/tools/driver/driver.cpp:405:12
#45 0x00000000027351ad main /usr/src/usr.bin/clang/clang/clang-driver.cpp:17:10
#46 0x000000082d4a15ea __libc_start1 /usr/src/lib/libc/csu/libc_start1.c:157:2
Abort trap

I'm currently reducing the test case for a separate ticket.

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.

6 participants