From 2a4f26b4c28aaf9307e690b2f743ffcde5183b9e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 13 Aug 2019 17:15:42 +0000 Subject: [PATCH] [ValueTracking] Improve reverse assumption inference Use isGuaranteedToTransferExecutionToSuccessor() instead of isSafeToSpeculativelyExecute() when seeing whether we can propagate the information in an assume backwards in isValidAssumeForContext(). The latter is more general - it also allows arbitrary loads/stores - and is also the condition we want: if our assume is guaranteed to execute, its condition not holding would be UB. Original patch by arielb1. Differential Revision: https://reviews.llvm.org/D37215 llvm-svn: 368723 --- llvm/lib/Analysis/ValueTracking.cpp | 8 +++++++- llvm/test/Transforms/InstCombine/assume_inevitable.ll | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c09530c..2773b60 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -558,12 +558,18 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv, return true; } + // Don't let an assume affect itself - this would cause the problems + // `isEphemeralValueOf` is trying to prevent, and it would also make + // the loop below go out of bounds. + if (Inv == CxtI) + return false; + // The context comes first, but they're both in the same block. Make sure // there is nothing in between that might interrupt the control flow. for (BasicBlock::const_iterator I = std::next(BasicBlock::const_iterator(CxtI)), IE(Inv); I != IE; ++I) - if (!isSafeToSpeculativelyExecute(&*I) && !isAssumeLikeIntrinsic(&*I)) + if (!isGuaranteedToTransferExecutionToSuccessor(&*I)) return false; return !isEphemeralValueOf(Inv, CxtI); diff --git a/llvm/test/Transforms/InstCombine/assume_inevitable.ll b/llvm/test/Transforms/InstCombine/assume_inevitable.ll index a063775..d048977 100644 --- a/llvm/test/Transforms/InstCombine/assume_inevitable.ll +++ b/llvm/test/Transforms/InstCombine/assume_inevitable.ll @@ -8,10 +8,10 @@ define i32 @assume_inevitable(i32* %a, i32* %b, i8* %c) { ; CHECK-LABEL: @assume_inevitable( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[M:%.*]] = alloca i64, align 8 -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 32 ; CHECK-NEXT: [[LOADRES:%.*]] = load i32, i32* [[B:%.*]], align 4 ; CHECK-NEXT: [[LOADRES2:%.*]] = call i32 @llvm.annotation.i32(i32 [[LOADRES]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2) -; CHECK-NEXT: store i32 [[LOADRES2]], i32* [[A]], align 4 +; CHECK-NEXT: store i32 [[LOADRES2]], i32* [[A]], align 32 ; CHECK-NEXT: [[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[DUMMY_EQ]]) ; CHECK-NEXT: [[M_I8:%.*]] = bitcast i64* [[M]] to i8* -- 2.7.4