Skip to content

Commit 5b83261

Browse files
committed
[DivRemPairs] make sure we have a valid CFG for hoisting division
This transform was added with e38b7e8 and as shown in: https://llvm.org/PR51241 ...it could crash without an extra check of the blocks. There might be a more compact way to write this constraint, but we can't just count the successors/predecessors without affecting a test that includes a switch instruction.
1 parent d3c70d9 commit 5b83261

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

llvm/lib/Transforms/Scalar/DivRemPairs.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,10 @@ static bool optimizeDivRem(Function &F, const TargetTransformInfo &TTI,
272272

273273
if (PredBB && IsSafeToHoist(RemInst, RemBB) &&
274274
IsSafeToHoist(DivInst, DivBB) &&
275-
llvm::all_of(successors(PredBB), [&](BasicBlock *BB) {
276-
return BB == DivBB || BB == RemBB;
277-
})) {
275+
all_of(successors(PredBB),
276+
[&](BasicBlock *BB) { return BB == DivBB || BB == RemBB; }) &&
277+
all_of(predecessors(DivBB),
278+
[&](BasicBlock *BB) { return BB == RemBB || BB == PredBB; })) {
278279
DivDominates = true;
279280
DivInst->moveBefore(PredBB->getTerminator());
280281
Changed = true;

llvm/test/Transforms/DivRemPairs/X86/div-expanded-rem-pair.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,35 @@ return: ; preds = %if.then, %if.end3
529529
%retval.0 = phi i64 [ %div, %if.end3 ], [ 0, %if.then ]
530530
ret i64 %retval.0
531531
}
532+
533+
; Negative test (this would create invalid IR and crash).
534+
; The div block can't have predecessors other than the rem block
535+
; and the common single pred block (it is reachable from entry here).
536+
537+
define i32 @PR51241(i1 %b1, i1 %b2, i32 %t0) {
538+
; CHECK-LABEL: @PR51241(
539+
; CHECK-NEXT: entry:
540+
; CHECK-NEXT: br i1 [[B1:%.*]], label [[DIVBB:%.*]], label [[PREDBB:%.*]]
541+
; CHECK: predbb:
542+
; CHECK-NEXT: br i1 [[B2:%.*]], label [[DIVBB]], label [[REMBB:%.*]]
543+
; CHECK: rembb:
544+
; CHECK-NEXT: [[REM2:%.*]] = srem i32 7, [[T0:%.*]]
545+
; CHECK-NEXT: br label [[DIVBB]]
546+
; CHECK: divbb:
547+
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 7, [[T0]]
548+
; CHECK-NEXT: ret i32 [[DIV]]
549+
;
550+
entry:
551+
br i1 %b1, label %divbb, label %predbb
552+
553+
predbb:
554+
br i1 %b2, label %divbb, label %rembb
555+
556+
rembb:
557+
%rem2 = srem i32 7, %t0
558+
br label %divbb
559+
560+
divbb:
561+
%div = sdiv i32 7, %t0
562+
ret i32 %div
563+
}

0 commit comments

Comments
 (0)