From: Brian M. Rzycki Date: Tue, 13 Mar 2018 18:14:10 +0000 (+0000) Subject: [LazyValueInfo] PR33357 prevent infinite recursion on BinaryOperator X-Git-Tag: android-x86-7.1-r4~3856 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b2e9134e8c57ac3ced23b99643ca63c0b11b96b6;p=android-x86%2Fexternal-llvm.git [LazyValueInfo] PR33357 prevent infinite recursion on BinaryOperator Summary: It is possible for LVI to encounter instructions that are not in valid SSA form and reference themselves. One example is the following: %tmp4 = and i1 %tmp4, undef Before this patch LVI would recurse until running out of stack memory and crashed. This patch marks these self-referential instructions as Overdefined and aborts analysis on the instruction. Fixes https://bugs.llvm.org/show_bug.cgi?id=33357 Reviewers: craig.topper, anna, efriedma, dberlin, sebpop, kuhar Reviewed by: dberlin Subscribers: uabelho, spatel, a.elovikov, fhahn, eli.friedman, mzolotukhin, spop, evandro, davide, llvm-commits Differential Revision: https://reviews.llvm.org/D34135 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327432 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 65fd007dc0b..36e66f7f6ef 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -1145,9 +1145,17 @@ getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest, (!isTrueDest && BO->getOpcode() != BinaryOperator::Or)) return ValueLatticeElement::getOverdefined(); - auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited); - auto LHS = getValueFromCondition(Val, BO->getOperand(1), isTrueDest, Visited); - return intersect(RHS, LHS); + // Prevent infinite recursion if Cond references itself as in this example: + // Cond: "%tmp4 = and i1 %tmp4, undef" + // BL: "%tmp4 = and i1 %tmp4, undef" + // BR: "i1 undef" + Value *BL = BO->getOperand(0); + Value *BR = BO->getOperand(1); + if (BL == Cond || BR == Cond) + return ValueLatticeElement::getOverdefined(); + + return intersect(getValueFromCondition(Val, BL, isTrueDest, Visited), + getValueFromCondition(Val, BR, isTrueDest, Visited)); } static ValueLatticeElement diff --git a/test/Transforms/JumpThreading/PR33357-lvi-recursion.ll b/test/Transforms/JumpThreading/PR33357-lvi-recursion.ll new file mode 100644 index 00000000000..e328f32c9c3 --- /dev/null +++ b/test/Transforms/JumpThreading/PR33357-lvi-recursion.ll @@ -0,0 +1,37 @@ +; RUN: opt -S -jump-threading -verify -o - %s | FileCheck %s +@a = external global i16, align 1 + +; CHECK-LABEL: f +; CHECK: bb6: +; CHECK: bb2: +; CHECK: bb3: +; CHECK-NOT: bb0: +; CHECK-NOT: bb1: +; CHECK-NOT: bb4: +; CHECK-NOT: bb5: +define void @f(i32 %p1) { +bb0: + %0 = icmp eq i32 %p1, 0 + br i1 undef, label %bb6, label %bb1 + +bb1: + br label %bb2 + +bb2: + %1 = phi i1 [ %0, %bb1 ], [ %2, %bb4 ] + %2 = and i1 %1, undef + br i1 %2, label %bb3, label %bb4 + +bb3: + store i16 undef, i16* @a, align 1 + br label %bb4 + +bb4: + br i1 %0, label %bb2, label %bb5 + +bb5: + unreachable + +bb6: + ret void +}