diff --git a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h --- a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h +++ b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h @@ -16,6 +16,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEBUILDER_H #define LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEBUILDER_H +#include "llvm/Analysis/AssumeBundleQueries.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/PassManager.h" @@ -41,6 +42,11 @@ void salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr, DominatorTree *DT = nullptr); +IntrinsicInst *buildAssumeFromKnowledge(ArrayRef Knowledge, + Instruction *InsertPoint, + AssumptionCache *AC = nullptr, + DominatorTree *DT = nullptr); + /// This pass attempts to minimize the number of assume without loosing any /// information. struct AssumeSimplifyPass : public PassInfoMixin { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -42,13 +42,13 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" -#include "llvm/IR/IntrinsicsX86.h" -#include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsAArch64.h" +#include "llvm/IR/IntrinsicsAMDGPU.h" +#include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" -#include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsPowerPC.h" +#include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/PatternMatch.h" @@ -67,6 +67,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/InstCombine/InstCombineWorklist.h" +#include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SimplifyLibCalls.h" #include @@ -89,6 +90,8 @@ cl::desc("How wide an instruction window to bypass looking for " "another guard")); +extern cl::opt EnableKnowledgeRetention; + /// Return the specified type promoted as it would be to pass though a va_arg /// area. static Type *getPromotedType(Type *Ty) { @@ -4212,15 +4215,19 @@ Value *IIOperand = II->getArgOperand(0); SmallVector OpBundles; II->getOperandBundlesAsDefs(OpBundles); - bool HasOpBundles = !OpBundles.empty(); + auto RemoveConditionFromAssume = [&](Instruction *Assume) -> Instruction * { + assert(isa(Assume)); + if (isAssumeWithEmptyBundle(*cast(II))) + return eraseInstFromFunction(CI); + replaceUse(II->getOperandUse(0), ConstantInt::getFalse(II->getContext())); + return nullptr; + }; // Remove an assume if it is followed by an identical assume. // TODO: Do we need this? Unless there are conflicting assumptions, the // computeKnownBits(IIOperand) below here eliminates redundant assumes. Instruction *Next = II->getNextNonDebugInstruction(); - if (HasOpBundles && - match(Next, m_Intrinsic(m_Specific(IIOperand))) && - !cast(Next)->hasOperandBundles()) - return eraseInstFromFunction(CI); + if (match(Next, m_Intrinsic(m_Specific(IIOperand)))) + return RemoveConditionFromAssume(Next); // Canonicalize assume(a && b) -> assume(a); assume(b); // Note: New assumption intrinsics created here are registered by @@ -4243,9 +4250,43 @@ return eraseInstFromFunction(*II); } + CmpInst::Predicate Pred; + if (EnableKnowledgeRetention && + match(IIOperand, m_Cmp(Pred, m_Value(A), m_Zero())) && + Pred == CmpInst::ICMP_NE && A->getType()->isPointerTy()) { + if (IntrinsicInst *Replacement = buildAssumeFromKnowledge( + {RetainedKnowledge{Attribute::NonNull, 0, A}}, Next, &AC, &DT)) + Replacement->insertBefore(Next); + if (isAssumeWithEmptyBundle(*cast(II))) + return eraseInstFromFunction(CI); + else + replaceUse(II->getOperandUse(0), + ConstantInt::getFalse(II->getContext())); + return RemoveConditionFromAssume(II); + } + + uint64_t AlignMask; + if (EnableKnowledgeRetention && + match(IIOperand, + m_Cmp(Pred, m_And(m_Value(A), m_ConstantInt(AlignMask)), + m_Zero())) && + Pred == CmpInst::ICMP_EQ) { + if (isPowerOf2_64(AlignMask + 1)) { + uint64_t Offset = 0; + match(A, m_Add(m_Value(A), m_ConstantInt(Offset))); + if (match(A, m_PtrToInt(m_Value(A)))) { + Value *OffsetV = nullptr; + LLVMContext &C = A->getContext(); + if (Offset) + OffsetV = ConstantInt::get(Type::getInt64Ty(C), Offset); + Builder.CreateAlignmentAssumption(DL, A, AlignMask + 1, OffsetV); + return RemoveConditionFromAssume(II); + } + } + } + // assume( (load addr) != null ) -> add 'nonnull' metadata to load // (if assume is valid at the load) - CmpInst::Predicate Pred; Instruction *LHS; if (match(IIOperand, m_ICmp(Pred, m_Instruction(LHS), m_Zero())) && Pred == ICmpInst::ICMP_NE && LHS->getOpcode() == Instruction::Load && @@ -4253,7 +4294,7 @@ isValidAssumeForContext(II, LHS, &DT)) { MDNode *MD = MDNode::get(II->getContext(), None); LHS->setMetadata(LLVMContext::MD_nonnull, MD); - if (!HasOpBundles) + if (isAssumeWithEmptyBundle(*II)) return eraseInstFromFunction(*II); // TODO: apply nonnull return attributes to calls and invokes diff --git a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp --- a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp +++ b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp @@ -280,6 +280,16 @@ } } +IntrinsicInst * +llvm::buildAssumeFromKnowledge(ArrayRef Knowledge, + Instruction *InsertPoint, AssumptionCache *AC, + DominatorTree *DT) { + AssumeBuilderState Builder(InsertPoint->getModule(), InsertPoint, AC, DT); + for (const RetainedKnowledge &RK : Knowledge) + Builder.addKnowledge(RK); + return Builder.build(); +} + namespace { struct AssumeSimplify { diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll --- a/llvm/test/Transforms/InstCombine/assume.ll +++ b/llvm/test/Transforms/InstCombine/assume.ll @@ -6,14 +6,20 @@ target triple = "x86_64-unknown-linux-gnu" define i32 @foo1(i32* %a) #0 { -; CHECK-LABEL: @foo1( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 32 -; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 -; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 -; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) -; CHECK-NEXT: ret i32 [[TMP0]] +; DEFAULT-LABEL: @foo1( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 32 +; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 +; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 +; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) +; DEFAULT-NEXT: ret i32 [[TMP0]] +; +; BUNDLES-LABEL: @foo1( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 32 +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] +; BUNDLES-NEXT: ret i32 [[TMP0]] ; ; SAME-LABEL: @foo1( ; SAME-NEXT: entry: @@ -39,14 +45,20 @@ } define i32 @foo2(i32* %a) #0 { -; CHECK-LABEL: @foo2( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A:%.*]] to i64 -; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 -; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 -; CHECK-NEXT: ret i32 [[TMP0]] +; DEFAULT-LABEL: @foo2( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A:%.*]] to i64 +; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 +; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) +; DEFAULT-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 +; DEFAULT-NEXT: ret i32 [[TMP0]] +; +; BUNDLES-LABEL: @foo2( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A:%.*]], i64 32) ] +; BUNDLES-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; BUNDLES-NEXT: ret i32 [[TMP0]] ; ; SAME-LABEL: @foo2( ; SAME-NEXT: entry: @@ -72,11 +84,11 @@ declare void @llvm.assume(i1) #1 define i32 @simple(i32 %a) #1 { -; CHECK-LABEL: @simple( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 4 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i32 4 +; SAME-LABEL: @simple( +; SAME-NEXT: entry: +; SAME-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 4 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i32 4 ; ; SAME-LABEL: @simple( ; SAME-NEXT: entry: @@ -93,12 +105,12 @@ } define i32 @can1(i1 %a, i1 %b, i1 %c) { -; CHECK-LABEL: @can1( -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @llvm.assume(i1 [[A:%.*]]) -; CHECK-NEXT: call void @llvm.assume(i1 [[B:%.*]]) -; CHECK-NEXT: call void @llvm.assume(i1 [[C:%.*]]) -; CHECK-NEXT: ret i32 5 +; SAME-LABEL: @can1( +; SAME-NEXT: entry: +; SAME-NEXT: call void @llvm.assume(i1 [[A:%.*]]) +; SAME-NEXT: call void @llvm.assume(i1 [[B:%.*]]) +; SAME-NEXT: call void @llvm.assume(i1 [[C:%.*]]) +; SAME-NEXT: ret i32 5 ; ; SAME-LABEL: @can1( ; SAME-NEXT: entry: @@ -117,13 +129,13 @@ } define i32 @can2(i1 %a, i1 %b, i1 %c) { -; CHECK-LABEL: @can2( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[A:%.*]], true -; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) -; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true -; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]]) -; CHECK-NEXT: ret i32 5 +; SAME-LABEL: @can2( +; SAME-NEXT: entry: +; SAME-NEXT: [[TMP0:%.*]] = xor i1 [[A:%.*]], true +; SAME-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; SAME-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true +; SAME-NEXT: call void @llvm.assume(i1 [[TMP1]]) +; SAME-NEXT: ret i32 5 ; ; SAME-LABEL: @can2( ; SAME-NEXT: entry: @@ -143,12 +155,12 @@ } define i32 @bar1(i32 %a) #0 { -; CHECK-LABEL: @bar1( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i32 1 +; SAME-LABEL: @bar1( +; SAME-NEXT: entry: +; SAME-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 +; SAME-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i32 1 ; ; SAME-LABEL: @bar1( ; SAME-NEXT: entry: @@ -169,12 +181,12 @@ } define i32 @bar2(i32 %a) #0 { -; CHECK-LABEL: @bar2( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i32 1 +; SAME-LABEL: @bar2( +; SAME-NEXT: entry: +; SAME-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 +; SAME-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i32 1 ; ; SAME-LABEL: @bar2( ; SAME-NEXT: entry: @@ -194,14 +206,14 @@ } define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 { -; CHECK-LABEL: @bar3( -; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void @llvm.assume(i1 [[X:%.*]]) -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: tail call void @llvm.assume(i1 [[Y:%.*]]) -; CHECK-NEXT: ret i32 1 +; SAME-LABEL: @bar3( +; SAME-NEXT: entry: +; SAME-NEXT: tail call void @llvm.assume(i1 [[X:%.*]]) +; SAME-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 +; SAME-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: tail call void @llvm.assume(i1 [[Y:%.*]]) +; SAME-NEXT: ret i32 1 ; ; SAME-LABEL: @bar3( ; SAME-NEXT: entry: @@ -229,14 +241,14 @@ } define i32 @bar4(i32 %a, i32 %b) { -; CHECK-LABEL: @bar4( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B:%.*]] -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) -; CHECK-NEXT: ret i32 1 +; SAME-LABEL: @bar4( +; SAME-NEXT: entry: +; SAME-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 7 +; SAME-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 1 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B:%.*]] +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) +; SAME-NEXT: ret i32 1 ; ; SAME-LABEL: @bar4( ; SAME-NEXT: entry: @@ -262,10 +274,10 @@ } define i32 @icmp1(i32 %a) #0 { -; CHECK-LABEL: @icmp1( -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i32 1 +; SAME-LABEL: @icmp1( +; SAME-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i32 1 ; ; SAME-LABEL: @icmp1( ; SAME-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 @@ -279,10 +291,10 @@ } define i32 @icmp2(i32 %a) #0 { -; CHECK-LABEL: @icmp2( -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i32 0 +; SAME-LABEL: @icmp2( +; SAME-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i32 0 ; ; SAME-LABEL: @icmp2( ; SAME-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5 @@ -299,10 +311,10 @@ ; If the 'not' of a condition is known true, then the condition must be false. define i1 @assume_not(i1 %cond) { -; CHECK-LABEL: @assume_not( -; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true -; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) -; CHECK-NEXT: ret i1 false +; SAME-LABEL: @assume_not( +; SAME-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true +; SAME-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) +; SAME-NEXT: ret i1 false ; ; SAME-LABEL: @assume_not( ; SAME-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true @@ -319,10 +331,10 @@ ; Canonicalize a nonnull assumption on a load into metadata form. define i32 @bundle1(i32* %P) { -; CHECK-LABEL: @bundle1( -; CHECK-NEXT: tail call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P:%.*]]) ] -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[P]], align 4 -; CHECK-NEXT: ret i32 [[LOAD]] +; SAME-LABEL: @bundle1( +; SAME-NEXT: tail call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P:%.*]]) ] +; SAME-NEXT: [[LOAD:%.*]] = load i32, i32* [[P]], align 4 +; SAME-NEXT: ret i32 [[LOAD]] ; ; SAME-LABEL: @bundle1( ; SAME-NEXT: tail call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P:%.*]]) ] @@ -335,9 +347,9 @@ } define i32 @bundle2(i32* %P) { -; CHECK-LABEL: @bundle2( -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[P:%.*]], align 4 -; CHECK-NEXT: ret i32 [[LOAD]] +; SAME-LABEL: @bundle2( +; SAME-NEXT: [[LOAD:%.*]] = load i32, i32* [[P:%.*]], align 4 +; SAME-NEXT: ret i32 [[LOAD]] ; ; SAME-LABEL: @bundle2( ; SAME-NEXT: [[LOAD:%.*]] = load i32, i32* [[P:%.*]], align 4 @@ -349,10 +361,16 @@ } define i1 @nonnull1(i32** %a) { -; CHECK-LABEL: @nonnull1( -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8, !nonnull !6 -; CHECK-NEXT: tail call void @escape(i32* nonnull [[LOAD]]) -; CHECK-NEXT: ret i1 false +; DEFAULT-LABEL: @nonnull1( +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8, !nonnull !6 +; DEFAULT-NEXT: tail call void @escape(i32* nonnull [[LOAD]]) +; DEFAULT-NEXT: ret i1 false +; +; BUNDLES-LABEL: @nonnull1( +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[LOAD]]) ] +; BUNDLES-NEXT: tail call void @escape(i32* nonnull [[LOAD]]) +; BUNDLES-NEXT: ret i1 false ; ; SAME-LABEL: @nonnull1( ; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8, !nonnull !6 @@ -371,11 +389,11 @@ ; to pointer types. Doing otherwise would be illegal. define i1 @nonnull2(i32* %a) { -; CHECK-LABEL: @nonnull2( -; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[A:%.*]], align 4 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LOAD]], 0 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i1 false +; SAME-LABEL: @nonnull2( +; SAME-NEXT: [[LOAD:%.*]] = load i32, i32* [[A:%.*]], align 4 +; SAME-NEXT: [[CMP:%.*]] = icmp ne i32 [[LOAD]], 0 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i1 false ; ; SAME-LABEL: @nonnull2( ; SAME-NEXT: [[LOAD:%.*]] = load i32, i32* [[A:%.*]], align 4 @@ -394,17 +412,27 @@ ; if the assume is control dependent on something else define i1 @nonnull3(i32** %a, i1 %control) { -; CHECK-LABEL: @nonnull3( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] -; CHECK: taken: -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i1 false -; CHECK: not_taken: -; CHECK-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null -; CHECK-NEXT: ret i1 [[RVAL_2]] +; DEFAULT-LABEL: @nonnull3( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; DEFAULT-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; DEFAULT-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; DEFAULT: taken: +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; DEFAULT-NEXT: ret i1 false +; DEFAULT: not_taken: +; DEFAULT-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null +; DEFAULT-NEXT: ret i1 [[RVAL_2]] +; +; BUNDLES-LABEL: @nonnull3( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; BUNDLES: taken: +; BUNDLES-NEXT: ret i1 false +; BUNDLES: not_taken: +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null +; BUNDLES-NEXT: ret i1 [[RVAL_2]] ; ; SAME-LABEL: @nonnull3( ; SAME-NEXT: entry: @@ -436,12 +464,18 @@ ; interrupted by an exception being thrown define i1 @nonnull4(i32** %a) { -; CHECK-LABEL: @nonnull4( -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: tail call void @escape(i32* [[LOAD]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i1 false +; DEFAULT-LABEL: @nonnull4( +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; DEFAULT-NEXT: tail call void @escape(i32* [[LOAD]]) +; DEFAULT-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; DEFAULT-NEXT: ret i1 false +; +; BUNDLES-LABEL: @nonnull4( +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: tail call void @escape(i32* [[LOAD]]) +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[LOAD]]) ] +; BUNDLES-NEXT: ret i1 false ; ; SAME-LABEL: @nonnull4( ; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 @@ -459,12 +493,12 @@ ret i1 %rval } define i1 @nonnull5(i32** %a) { -; CHECK-LABEL: @nonnull5( -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: tail call void @escape(i32* [[LOAD]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32* [[LOAD]], null -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i1 false +; SAME-LABEL: @nonnull5( +; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; SAME-NEXT: tail call void @escape(i32* [[LOAD]]) +; SAME-NEXT: [[CMP:%.*]] = icmp slt i32* [[LOAD]], null +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP]]) +; SAME-NEXT: ret i1 false ; ; SAME-LABEL: @nonnull5( ; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 @@ -486,12 +520,12 @@ ; PR35846 - https://bugs.llvm.org/show_bug.cgi?id=35846 define i32 @assumption_conflicts_with_known_bits(i32 %a, i32 %b) { -; CHECK-LABEL: @assumption_conflicts_with_known_bits( -; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], 3 -; CHECK-NEXT: tail call void @llvm.assume(i1 false) -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[AND1]], 0 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) -; CHECK-NEXT: ret i32 0 +; SAME-LABEL: @assumption_conflicts_with_known_bits( +; SAME-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], 3 +; SAME-NEXT: tail call void @llvm.assume(i1 false) +; SAME-NEXT: [[CMP2:%.*]] = icmp eq i32 [[AND1]], 0 +; SAME-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) +; SAME-NEXT: ret i32 0 ; ; SAME-LABEL: @assumption_conflicts_with_known_bits( ; SAME-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], 3 @@ -516,15 +550,23 @@ ; get in the way of the fold. define void @debug_interference(i8 %x) { -; CHECK-LABEL: @debug_interference( -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0 -; CHECK-NEXT: tail call void @llvm.assume(i1 false) -; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 -; CHECK-NEXT: tail call void @llvm.assume(i1 false) -; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 -; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) -; CHECK-NEXT: ret void +; DEFAULT-LABEL: @debug_interference( +; DEFAULT-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0 +; DEFAULT-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 +; DEFAULT-NEXT: tail call void @llvm.assume(i1 false) +; DEFAULT-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 +; DEFAULT-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !7, metadata !DIExpression()), !dbg !9 +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) +; DEFAULT-NEXT: ret void +; +; BUNDLES-LABEL: @debug_interference( +; BUNDLES-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0 +; BUNDLES-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !6, metadata !DIExpression()), !dbg !8 +; BUNDLES-NEXT: tail call void @llvm.assume(i1 false) +; BUNDLES-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !6, metadata !DIExpression()), !dbg !8 +; BUNDLES-NEXT: tail call void @llvm.dbg.value(metadata i32 5, metadata !6, metadata !DIExpression()), !dbg !8 +; BUNDLES-NEXT: tail call void @llvm.assume(i1 [[CMP2]]) +; BUNDLES-NEXT: ret void ; ; SAME-LABEL: @debug_interference( ; SAME-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0 @@ -552,12 +594,12 @@ ; Does it ever make sense to peek through a bitcast of the icmp operand? define i32 @PR40940(<4 x i8> %x) { -; CHECK-LABEL: @PR40940( -; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> -; CHECK-NEXT: [[T2:%.*]] = bitcast <4 x i8> [[SHUF]] to i32 -; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 65536 -; CHECK-NEXT: call void @llvm.assume(i1 [[T3]]) -; CHECK-NEXT: ret i32 [[T2]] +; SAME-LABEL: @PR40940( +; SAME-NEXT: [[SHUF:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> +; SAME-NEXT: [[T2:%.*]] = bitcast <4 x i8> [[SHUF]] to i32 +; SAME-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 65536 +; SAME-NEXT: call void @llvm.assume(i1 [[T3]]) +; SAME-NEXT: ret i32 [[T2]] ; ; SAME-LABEL: @PR40940( ; SAME-NEXT: [[SHUF:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> @@ -574,17 +616,29 @@ } define i1 @nonnull3A(i32** %a, i1 %control) { -; CHECK-LABEL: @nonnull3A( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] -; CHECK: taken: -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) -; CHECK-NEXT: ret i1 true -; CHECK: not_taken: -; CHECK-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null -; CHECK-NEXT: ret i1 [[RVAL_2]] +; DEFAULT-LABEL: @nonnull3A( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; DEFAULT-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; DEFAULT: taken: +; DEFAULT-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; DEFAULT-NEXT: call void @llvm.assume(i1 [[CMP]]) +; DEFAULT-NEXT: ret i1 true +; DEFAULT: not_taken: +; DEFAULT-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null +; DEFAULT-NEXT: ret i1 [[RVAL_2]] +; +; BUNDLES-LABEL: @nonnull3A( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; BUNDLES: taken: +; BUNDLES-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[LOAD]]) ] +; BUNDLES-NEXT: ret i1 [[CMP]] +; BUNDLES: not_taken: +; BUNDLES-NEXT: [[RVAL_2:%.*]] = icmp sgt i32* [[LOAD]], null +; BUNDLES-NEXT: ret i1 [[RVAL_2]] ; ; SAME-LABEL: @nonnull3A( ; SAME-NEXT: entry: @@ -611,17 +665,96 @@ ret i1 %rval.2 } +define i1 @nonnull3E(i32** %a) { +; DEFAULT-LABEL: @nonnull3E( +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; DEFAULT-NEXT: [[NULL:%.*]] = icmp ne i32* [[LOAD]], null +; DEFAULT-NEXT: call void @llvm.assume(i1 [[NULL]]) +; DEFAULT-NEXT: ret i1 false +; +; BUNDLES-LABEL: @nonnull3E( +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[LOAD]]) ] +; BUNDLES-NEXT: ret i1 false +; + %load = load i32*, i32** %a + %null = icmp ne i32* %load, null + call void @llvm.assume(i1 %null) + ret i1 false +} + +define i32* @align1(i32** %a) { +; DEFAULT-LABEL: @align1( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A:%.*]], align 4 +; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint i32** [[A]] to i64 +; DEFAULT-NEXT: [[OFFSETEDINT:%.*]] = add i64 [[PTRINT]], 16 +; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[OFFSETEDINT]], 127 +; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) +; DEFAULT-NEXT: ret i32* [[TMP0]] +; +; BUNDLES-LABEL: @align1( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A:%.*]], align 4 +; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[A]], i64 128, i64 16) ] +; BUNDLES-NEXT: ret i32* [[TMP0]] +; +entry: + %0 = load i32*, i32** %a, align 4 + + %ptrint = ptrtoint i32** %a to i64 + %offsetedint = add i64 %ptrint, 16 + %maskedptr = and i64 %offsetedint, 127 + %maskcond = icmp eq i64 %maskedptr, 0 + tail call void @llvm.assume(i1 %maskcond) + + ret i32* %0 +} + +define i32* @align2(i32** %a) { +; SAME-LABEL: @align2( +; SAME-NEXT: entry: +; SAME-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A:%.*]], align 4 +; SAME-NEXT: [[PTRINT:%.*]] = ptrtoint i32** [[A]] to i64 +; SAME-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 85 +; SAME-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +; SAME-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) +; SAME-NEXT: ret i32* [[TMP0]] +; +entry: + %0 = load i32*, i32** %a, align 4 + + %ptrint = ptrtoint i32** %a to i64 + %maskedptr = and i64 %ptrint, 85 + %maskcond = icmp eq i64 %maskedptr, 0 + tail call void @llvm.assume(i1 %maskcond) + + ret i32* %0 +} + define i1 @nonnull3B(i32** %a, i1 %control) { -; CHECK-LABEL: @nonnull3B( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] -; CHECK: taken: -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) [ "nonnull"(i32* [[LOAD]]), "nonnull"(i1 [[CMP]]) ] -; CHECK-NEXT: ret i1 true -; CHECK: not_taken: -; CHECK-NEXT: ret i1 [[CONTROL]] +; DEFAULT-LABEL: @nonnull3B( +; DEFAULT-NEXT: entry: +; DEFAULT-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; DEFAULT: taken: +; DEFAULT-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; DEFAULT-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; DEFAULT-NEXT: call void @llvm.assume(i1 [[CMP]]) [ "nonnull"(i32* [[LOAD]]), "nonnull"(i1 [[CMP]]) ] +; DEFAULT-NEXT: ret i1 true +; DEFAULT: not_taken: +; DEFAULT-NEXT: ret i1 [[CONTROL]] +; +; BUNDLES-LABEL: @nonnull3B( +; BUNDLES-NEXT: entry: +; BUNDLES-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; BUNDLES: taken: +; BUNDLES-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; BUNDLES-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; BUNDLES-NEXT: call void @llvm.assume(i1 false) [ "nonnull"(i32* [[LOAD]]), "nonnull"(i1 [[CMP]]) ] +; BUNDLES-NEXT: ret i1 [[CMP]] +; BUNDLES: not_taken: +; BUNDLES-NEXT: ret i1 [[CONTROL]] ; ; SAME-LABEL: @nonnull3B( ; SAME-NEXT: entry: @@ -649,18 +782,18 @@ declare i1 @tmp1(i1) define i1 @nonnull3C(i32** %a, i1 %control) { -; CHECK-LABEL: @nonnull3C( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] -; CHECK: taken: -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: [[CMP2:%.*]] = call i1 @tmp1(i1 [[CMP]]) -; CHECK-NEXT: br label [[EXIT:%.*]] -; CHECK: exit: -; CHECK-NEXT: ret i1 [[CMP2]] -; CHECK: not_taken: -; CHECK-NEXT: ret i1 [[CONTROL]] +; SAME-LABEL: @nonnull3C( +; SAME-NEXT: entry: +; SAME-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; SAME: taken: +; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; SAME-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; SAME-NEXT: [[CMP2:%.*]] = call i1 @tmp1(i1 [[CMP]]) +; SAME-NEXT: br label [[EXIT:%.*]] +; SAME: exit: +; SAME-NEXT: ret i1 [[CMP2]] +; SAME: not_taken: +; SAME-NEXT: ret i1 [[CONTROL]] ; ; SAME-LABEL: @nonnull3C( ; SAME-NEXT: entry: @@ -692,19 +825,19 @@ } define i1 @nonnull3D(i32** %a, i1 %control) { -; CHECK-LABEL: @nonnull3D( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] -; CHECK: taken: -; CHECK-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null -; CHECK-NEXT: [[CMP2:%.*]] = call i1 @tmp1(i1 [[CMP]]) -; CHECK-NEXT: br label [[EXIT:%.*]] -; CHECK: exit: -; CHECK-NEXT: ret i1 [[CMP2]] -; CHECK: not_taken: -; CHECK-NEXT: call void @llvm.assume(i1 true) [ "ignore"(i32* undef), "ignore"(i1 undef), "nonnull"(i1 [[CONTROL]]) ] -; CHECK-NEXT: ret i1 [[CONTROL]] +; SAME-LABEL: @nonnull3D( +; SAME-NEXT: entry: +; SAME-NEXT: br i1 [[CONTROL:%.*]], label [[TAKEN:%.*]], label [[NOT_TAKEN:%.*]] +; SAME: taken: +; SAME-NEXT: [[LOAD:%.*]] = load i32*, i32** [[A:%.*]], align 8 +; SAME-NEXT: [[CMP:%.*]] = icmp ne i32* [[LOAD]], null +; SAME-NEXT: [[CMP2:%.*]] = call i1 @tmp1(i1 [[CMP]]) +; SAME-NEXT: br label [[EXIT:%.*]] +; SAME: exit: +; SAME-NEXT: ret i1 [[CMP2]] +; SAME: not_taken: +; SAME-NEXT: call void @llvm.assume(i1 true) [ "ignore"(i32* undef), "ignore"(i1 undef), "nonnull"(i1 [[CONTROL]]) ] +; SAME-NEXT: ret i1 [[CONTROL]] ; ; SAME-LABEL: @nonnull3D( ; SAME-NEXT: entry: @@ -736,8 +869,8 @@ define void @always_true_assumption() { -; CHECK-LABEL: @always_true_assumption( -; CHECK-NEXT: ret void +; SAME-LABEL: @always_true_assumption( +; SAME-NEXT: ret void ; ; SAME-LABEL: @always_true_assumption( ; SAME-NEXT: ret void @@ -751,11 +884,11 @@ ; The assume says the opposite. Make sure we don't crash. define i64 @PR31809() { -; CHECK-LABEL: @PR31809( -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: [[T1:%.*]] = ptrtoint i32* [[A]] to i64 -; CHECK-NEXT: call void @llvm.assume(i1 false) -; CHECK-NEXT: ret i64 [[T1]] +; SAME-LABEL: @PR31809( +; SAME-NEXT: [[A:%.*]] = alloca i32, align 4 +; SAME-NEXT: [[T1:%.*]] = ptrtoint i32* [[A]] to i64 +; SAME-NEXT: call void @llvm.assume(i1 false) +; SAME-NEXT: ret i64 [[T1]] ; ; SAME-LABEL: @PR31809( ; SAME-NEXT: [[A:%.*]] = alloca i32, align 4 @@ -774,11 +907,11 @@ ; so just don't crash. define i8 @conflicting_assumptions(i8 %x){ -; CHECK-LABEL: @conflicting_assumptions( -; CHECK-NEXT: call void @llvm.assume(i1 false) -; CHECK-NEXT: [[COND2:%.*]] = icmp eq i8 [[X:%.*]], 4 -; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]]) -; CHECK-NEXT: ret i8 5 +; SAME-LABEL: @conflicting_assumptions( +; SAME-NEXT: call void @llvm.assume(i1 false) +; SAME-NEXT: [[COND2:%.*]] = icmp eq i8 [[X:%.*]], 4 +; SAME-NEXT: call void @llvm.assume(i1 [[COND2]]) +; SAME-NEXT: ret i8 5 ; ; SAME-LABEL: @conflicting_assumptions( ; SAME-NEXT: call void @llvm.assume(i1 false) @@ -798,9 +931,9 @@ ; try to set more known bits than existed in the known bits struct. define void @PR36270(i32 %b) { -; CHECK-LABEL: @PR36270( -; CHECK-NEXT: tail call void @llvm.assume(i1 false) -; CHECK-NEXT: unreachable +; SAME-LABEL: @PR36270( +; SAME-NEXT: tail call void @llvm.assume(i1 false) +; SAME-NEXT: unreachable ; ; SAME-LABEL: @PR36270( ; SAME-NEXT: tail call void @llvm.assume(i1 false)