diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h @@ -0,0 +1,290 @@ +//===- InstSimplifyFolder.h - InstSimplify folding helper --------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the InstSimplifyFolder class, a helper for IRBuilder. +// It provides IRBuilder with a set of methods for folding operations to +// existing values using InstructionSimplify. At the moment, only a subset of +// the implementation uses InstructionSimplify. The rest of the implementation +// only folds constants. +// +// The folder also applies constant folding using a provided folder. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H +#define LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/IRBuilderFolder.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" + +namespace llvm { + +/// InstSimplifyFolder - Use InstructionSimplify to fold operations to existing +/// values. Also applies target-specific constant folding. +class InstSimplifyFolder final : public IRBuilderFolder { + virtual void anchor(); + + const DataLayout &DL; + + IRBuilderFolder &ConstantFolder; + +public: + InstSimplifyFolder(const DataLayout &DL, IRBuilderFolder &ConstantFolder) + : DL(DL), ConstantFolder(ConstantFolder) {} + + //===--------------------------------------------------------------------===// + // Value-based folders. + // + // Return an existing value or a constant if the operation can be simplified. + // Otherwise return nullptr. + //===--------------------------------------------------------------------===// + Value *FoldOr(Value *LHS, Value *RHS) const override { + if (auto *LC = dyn_cast_or_null(LHS)) + if (auto *RC = dyn_cast_or_null(RHS)) + return ConstantFolder.FoldOr(LHS, RHS); + return SimplifyOrInst(LHS, RHS, SimplifyQuery(DL)); + } + + //===--------------------------------------------------------------------===// + // Binary Operators + //===--------------------------------------------------------------------===// + + Value *CreateAdd(Constant *LHS, Constant *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return ConstantFolder.CreateAdd(LHS, RHS, HasNUW, HasNSW); + } + Value *CreateFAdd(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateFAdd(LHS, RHS); + } + Value *CreateSub(Constant *LHS, Constant *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return ConstantFolder.CreateSub(LHS, RHS, HasNUW, HasNSW); + } + Value *CreateFSub(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateFSub(LHS, RHS); + } + Value *CreateMul(Constant *LHS, Constant *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return ConstantFolder.CreateMul(LHS, RHS, HasNUW, HasNSW); + } + Value *CreateFMul(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateFMul(LHS, RHS); + } + Value *CreateUDiv(Constant *LHS, Constant *RHS, + bool isExact = false) const override { + return ConstantFolder.CreateUDiv(LHS, RHS, isExact); + } + Value *CreateSDiv(Constant *LHS, Constant *RHS, + bool isExact = false) const override { + return ConstantFolder.CreateSDiv(LHS, RHS, isExact); + } + Value *CreateFDiv(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateFDiv(LHS, RHS); + } + Value *CreateURem(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateURem(LHS, RHS); + } + Value *CreateSRem(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateSRem(LHS, RHS); + } + Value *CreateFRem(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateFRem(LHS, RHS); + } + Value *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return ConstantFolder.CreateShl(LHS, RHS, HasNUW, HasNSW); + } + Value *CreateLShr(Constant *LHS, Constant *RHS, + bool isExact = false) const override { + return ConstantFolder.CreateLShr(LHS, RHS, isExact); + } + Value *CreateAShr(Constant *LHS, Constant *RHS, + bool isExact = false) const override { + return ConstantFolder.CreateAShr(LHS, RHS, isExact); + } + Value *CreateAnd(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateAnd(LHS, RHS); + } + Value *CreateXor(Constant *LHS, Constant *RHS) const override { + return ConstantFolder.CreateXor(LHS, RHS); + } + + Value *CreateBinOp(Instruction::BinaryOps Opc, Constant *LHS, + Constant *RHS) const override { + return ConstantFolder.CreateBinOp(Opc, LHS, RHS); + } + + //===--------------------------------------------------------------------===// + // Unary Operators + //===--------------------------------------------------------------------===// + + Value *CreateNeg(Constant *C, bool HasNUW = false, + bool HasNSW = false) const override { + return ConstantFolder.CreateNeg(C, HasNUW, HasNSW); + } + Value *CreateFNeg(Constant *C) const override { + return ConstantFolder.CreateFNeg(C); + } + Value *CreateNot(Constant *C) const override { + return ConstantFolder.CreateNot(C); + } + + Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override { + return ConstantFolder.CreateUnOp(Opc, C); + } + + //===--------------------------------------------------------------------===// + // Memory Instructions + //===--------------------------------------------------------------------===// + + Value *CreateGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList) const override { + return ConstantFolder.CreateGetElementPtr(Ty, C, IdxList); + } + Value *CreateGetElementPtr(Type *Ty, Constant *C, + Constant *Idx) const override { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return ConstantFolder.CreateGetElementPtr(Ty, C, Idx); + } + Value *CreateGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList) const override { + return ConstantFolder.CreateGetElementPtr(Ty, C, IdxList); + } + + Value * + CreateInBoundsGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList) const override { + return ConstantFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList); + } + Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, + Constant *Idx) const override { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return ConstantFolder.CreateInBoundsGetElementPtr(Ty, C, Idx); + } + Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C, + ArrayRef IdxList) const override { + return ConstantFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList); + } + + //===--------------------------------------------------------------------===// + // Cast/Conversion Operators + //===--------------------------------------------------------------------===// + + Value *CreateCast(Instruction::CastOps Op, Constant *C, + Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateCast(Op, C, DestTy); + } + Value *CreateIntCast(Constant *C, Type *DestTy, + bool isSigned) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateIntCast(C, DestTy, isSigned); + } + Value *CreatePointerCast(Constant *C, Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreatePointerCast(C, DestTy); + } + Value *CreateFPCast(Constant *C, Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateFPCast(C, DestTy); + } + Value *CreateBitCast(Constant *C, Type *DestTy) const override { + return ConstantFolder.CreateBitCast(C, DestTy); + } + Value *CreateIntToPtr(Constant *C, Type *DestTy) const override { + return ConstantFolder.CreateIntToPtr(C, DestTy); + } + Value *CreatePtrToInt(Constant *C, Type *DestTy) const override { + return ConstantFolder.CreatePtrToInt(C, DestTy); + } + Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateZExtOrBitCast(C, DestTy); + } + Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateSExtOrBitCast(C, DestTy); + } + Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreateTruncOrBitCast(C, DestTy); + } + + Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C, + Type *DestTy) const override { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return ConstantFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy); + } + + //===--------------------------------------------------------------------===// + // Compare Instructions + //===--------------------------------------------------------------------===// + + Value *CreateICmp(CmpInst::Predicate P, Constant *LHS, + Constant *RHS) const override { + return ConstantFolder.CreateICmp(P, LHS, RHS); + } + Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, + Constant *RHS) const override { + return ConstantFolder.CreateFCmp(P, LHS, RHS); + } + + //===--------------------------------------------------------------------===// + // Other Instructions + //===--------------------------------------------------------------------===// + + Value *CreateSelect(Constant *C, Constant *True, + Constant *False) const override { + return ConstantFolder.CreateSelect(C, True, False); + } + + Value *CreateExtractElement(Constant *Vec, Constant *Idx) const override { + return ConstantFolder.CreateExtractElement(Vec, Idx); + } + + Value *CreateInsertElement(Constant *Vec, Constant *NewElt, + Constant *Idx) const override { + return ConstantFolder.CreateInsertElement(Vec, NewElt, Idx); + } + + Value *CreateShuffleVector(Constant *V1, Constant *V2, + ArrayRef Mask) const override { + return ConstantFolder.CreateShuffleVector(V1, V2, Mask); + } + + Value *CreateExtractValue(Constant *Agg, + ArrayRef IdxList) const override { + return ConstantFolder.CreateExtractValue(Agg, IdxList); + } + + Value *CreateInsertValue(Constant *Agg, Constant *Val, + ArrayRef IdxList) const override { + return ConstantFolder.CreateInsertValue(Agg, Val, IdxList); + } +}; + +} // end namespace llvm + +#endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h --- a/llvm/include/llvm/Analysis/TargetFolder.h +++ b/llvm/include/llvm/Analysis/TargetFolder.h @@ -102,8 +102,12 @@ Constant *CreateAnd(Constant *LHS, Constant *RHS) const override { return Fold(ConstantExpr::getAnd(LHS, RHS)); } - Constant *CreateOr(Constant *LHS, Constant *RHS) const override { - return Fold(ConstantExpr::getOr(LHS, RHS)); + Value *FoldOr(Value *LHS, Value *RHS) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return Fold(ConstantExpr::getOr(LC, RC)); + return nullptr; } Constant *CreateXor(Constant *LHS, Constant *RHS) const override { return Fold(ConstantExpr::getXor(LHS, RHS)); diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h --- a/llvm/include/llvm/IR/ConstantFolder.h +++ b/llvm/include/llvm/IR/ConstantFolder.h @@ -31,6 +31,20 @@ public: explicit ConstantFolder() = default; + //===--------------------------------------------------------------------===// + // Value-based folders. + // + // Return an existing value or a constant if the operation can be simplified. + // Otherwise return nullptr. + //===--------------------------------------------------------------------===// + Value *FoldOr(Value *LHS, Value *RHS) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return ConstantExpr::getOr(LC, RC); + return nullptr; + } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -107,7 +121,7 @@ return ConstantExpr::getAnd(LHS, RHS); } - Constant *CreateOr(Constant *LHS, Constant *RHS) const override { + Constant *CreateOr(Constant *LHS, Constant *RHS) const { return ConstantExpr::getOr(LHS, RHS); } diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1386,12 +1386,8 @@ } Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { - if (auto *RC = dyn_cast(RHS)) { - if (RC->isNullValue()) - return LHS; // LHS | 0 -> LHS - if (auto *LC = dyn_cast(LHS)) - return Insert(Folder.CreateOr(LC, RC), Name); - } + if (auto *V = Folder.FoldOr(LHS, RHS)) + return V; return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } diff --git a/llvm/include/llvm/IR/IRBuilderFolder.h b/llvm/include/llvm/IR/IRBuilderFolder.h --- a/llvm/include/llvm/IR/IRBuilderFolder.h +++ b/llvm/include/llvm/IR/IRBuilderFolder.h @@ -25,6 +25,14 @@ public: virtual ~IRBuilderFolder(); + //===--------------------------------------------------------------------===// + // Value-based folders. + // + // Return an existing value or a constant if the operation can be simplified. + // Otherwise return nullptr. + //===--------------------------------------------------------------------===// + virtual Value *FoldOr(Value *LHS, Value *RHS) const = 0; + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -53,7 +61,6 @@ virtual Value *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false) const = 0; virtual Value *CreateAnd(Constant *LHS, Constant *RHS) const = 0; - virtual Value *CreateOr(Constant *LHS, Constant *RHS) const = 0; virtual Value *CreateXor(Constant *LHS, Constant *RHS) const = 0; virtual Value *CreateBinOp(Instruction::BinaryOps Opc, Constant *LHS, Constant *RHS) const = 0; diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h --- a/llvm/include/llvm/IR/NoFolder.h +++ b/llvm/include/llvm/IR/NoFolder.h @@ -37,6 +37,14 @@ public: explicit NoFolder() = default; + //===--------------------------------------------------------------------===// + // Value-based folders. + // + // Return an existing value or a constant if the operation can be simplified. + // Otherwise return nullptr. + //===--------------------------------------------------------------------===// + Value *FoldOr(Value *LHS, Value *RHS) const override { return nullptr; } + //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// @@ -136,10 +144,6 @@ return BinaryOperator::CreateAnd(LHS, RHS); } - Instruction *CreateOr(Constant *LHS, Constant *RHS) const override { - return BinaryOperator::CreateOr(LHS, RHS); - } - Instruction *CreateXor(Constant *LHS, Constant *RHS) const override { return BinaryOperator::CreateXor(LHS, RHS); } diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h --- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h @@ -18,6 +18,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/InstSimplifyFolder.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionNormalization.h" #include "llvm/Analysis/TargetFolder.h" @@ -122,7 +123,8 @@ /// "expanded" form. bool LSRMode; - typedef IRBuilder BuilderType; + TargetFolder ConstantFolder; + typedef IRBuilder BuilderType; BuilderType Builder; // RAII object that stores the current insertion point and restores it when @@ -177,8 +179,8 @@ const char *name, bool PreserveLCSSA = true) : SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA), IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true), - LSRMode(false), - Builder(se.getContext(), TargetFolder(DL), + LSRMode(false), ConstantFolder(DL), + Builder(se.getContext(), InstSimplifyFolder(DL, ConstantFolder), IRBuilderCallbackInserter( [this](Instruction *I) { rememberInstruction(I); })) { #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/CmpInstAnalysis.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/InstSimplifyFolder.h" #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/OverflowInstAnalysis.h" @@ -6454,3 +6455,5 @@ template const SimplifyQuery getBestSimplifyQuery(AnalysisManager &, Function &); } + +void InstSimplifyFolder::anchor() {} diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -39,12 +39,12 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/InstSimplifyFolder.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/PtrUseVisitor.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" -#include "llvm/IR/ConstantFolder.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" @@ -137,7 +137,7 @@ }; /// Provide a type for IRBuilder that drops names in release builds. -using IRBuilderTy = IRBuilder; +using IRBuilderTy = IRBuilder; /// A used slice of an alloca. /// @@ -2285,6 +2285,7 @@ SmallSetVector &PHIUsers; SmallSetVector &SelectUsers; + ConstantFolder ConstFolder; // Utility IR builder, whose name prefix is setup for each visited use, and // the insertion point is set to point to the user. IRBuilderTy IRB; @@ -2312,7 +2313,7 @@ ElementSize(VecTy ? DL.getTypeSizeInBits(ElementTy).getFixedSize() / 8 : 0), PHIUsers(PHIUsers), SelectUsers(SelectUsers), - IRB(NewAI.getContext(), ConstantFolder()) { + IRB(NewAI.getContext(), InstSimplifyFolder(DL, ConstFolder)) { if (VecTy) { assert((DL.getTypeSizeInBits(ElementTy).getFixedSize() % 8) == 0 && "Only multiple-of-8 sized vector elements are viable"); @@ -3939,7 +3940,10 @@ // From here on, we can't fail and will be building new accesses, so rig up // an IR builder. - IRBuilderTy IRB(&AI); + ConstantFolder ConstFolder; + IRBuilderTy IRB( + AI.getParent(), AI.getIterator(), + InstSimplifyFolder(AI.getModule()->getDataLayout(), ConstFolder)); // Collect the new slices which we will merge into the alloca slices. SmallVector NewSlices; @@ -4604,7 +4608,10 @@ // First, split any FCA loads and stores touching this alloca to promote // better splitting and promotion opportunities. - IRBuilderTy IRB(&AI); + ConstantFolder ConstFolder; + IRBuilderTy IRB( + AI.getParent(), AI.getIterator(), + InstSimplifyFolder(AI.getModule()->getDataLayout(), ConstFolder)); AggLoadStoreRewriter AggRewriter(DL, IRB); Changed |= AggRewriter.rewrite(AI); diff --git a/llvm/test/Transforms/LoopDistribute/scev-inserted-runtime-check.ll b/llvm/test/Transforms/LoopDistribute/scev-inserted-runtime-check.ll --- a/llvm/test/Transforms/LoopDistribute/scev-inserted-runtime-check.ll +++ b/llvm/test/Transforms/LoopDistribute/scev-inserted-runtime-check.ll @@ -14,7 +14,6 @@ ; CHECK: for.body.lver.check: ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] ; CHECK-NEXT: [[MUL2:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 8, i64 [[TMP0]]) ; CHECK-NEXT: [[MUL_RESULT3:%.*]] = extractvalue { i64, i1 } [[MUL2]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW4:%.*]] = extractvalue { i64, i1 } [[MUL2]], 1 @@ -22,7 +21,7 @@ ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, i8* [[A5]], i64 [[MUL_RESULT3]] ; CHECK-NEXT: [[TMP15:%.*]] = icmp ult i8* [[TMP12]], [[A5]] ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP15]], [[MUL_OVERFLOW4]] -; CHECK-NEXT: [[TMP18:%.*]] = or i1 [[TMP8]], [[TMP17]] +; CHECK-NEXT: [[TMP18:%.*]] = or i1 [[TMP7]], [[TMP17]] ; CHECK-NEXT: br i1 [[TMP18]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]] ; CHECK: for.body.ph.lver.orig: ; CHECK-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]] @@ -149,7 +148,6 @@ ; CHECK: for.body.lver.check: ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] ; CHECK-NEXT: [[MUL2:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 8, i64 [[TMP0]]) ; CHECK-NEXT: [[MUL_RESULT3:%.*]] = extractvalue { i64, i1 } [[MUL2]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW4:%.*]] = extractvalue { i64, i1 } [[MUL2]], 1 @@ -157,7 +155,7 @@ ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i8, i8* bitcast (i32* getelementptr inbounds ([8192 x i32], [8192 x i32]* @global_a, i64 0, i64 42) to i8*), i64 [[MUL_RESULT3]] ; CHECK-NEXT: [[TMP15:%.*]] = icmp ult i8* [[TMP12]], bitcast (i32* getelementptr inbounds ([8192 x i32], [8192 x i32]* @global_a, i64 0, i64 42) to i8*) ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP15]], [[MUL_OVERFLOW4]] -; CHECK-NEXT: [[TMP18:%.*]] = or i1 [[TMP8]], [[TMP17]] +; CHECK-NEXT: [[TMP18:%.*]] = or i1 [[TMP7]], [[TMP17]] ; CHECK-NEXT: br i1 [[TMP18]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]] ; CHECK: for.body.ph.lver.orig: ; CHECK-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]] diff --git a/llvm/test/Transforms/LoopVectorize/runtime-check-small-clamped-bounds.ll b/llvm/test/Transforms/LoopVectorize/runtime-check-small-clamped-bounds.ll --- a/llvm/test/Transforms/LoopVectorize/runtime-check-small-clamped-bounds.ll +++ b/llvm/test/Transforms/LoopVectorize/runtime-check-small-clamped-bounds.ll @@ -20,8 +20,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i32 [[TMP0]], 3 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] -; CHECK-NEXT: br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]] ; CHECK: vector.memcheck: ; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 @@ -104,8 +103,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i32 [[TMP0]], 3 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] -; CHECK-NEXT: br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]] ; CHECK: vector.memcheck: ; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 @@ -267,8 +265,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i32 [[TMP0]], 3 -; CHECK-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] -; CHECK-NEXT: br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] +; CHECK-NEXT: br i1 [[TMP7]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N]], 2 ; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N]], [[N_MOD_VF]] diff --git a/llvm/test/Transforms/LoopVersioning/wrapping-pointer-versioning.ll b/llvm/test/Transforms/LoopVersioning/wrapping-pointer-versioning.ll --- a/llvm/test/Transforms/LoopVersioning/wrapping-pointer-versioning.ll +++ b/llvm/test/Transforms/LoopVersioning/wrapping-pointer-versioning.ll @@ -31,7 +31,6 @@ ; LV-NEXT: [[A5:%.*]] = bitcast i16* [[A:%.*]] to i8* ; LV-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 ; LV-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 -; LV-NEXT: [[TMP8:%.*]] = or i1 false, [[TMP7]] ; LV-NEXT: [[MUL2:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[TMP0]]) ; LV-NEXT: [[MUL_RESULT3:%.*]] = extractvalue { i64, i1 } [[MUL2]], 0 ; LV-NEXT: [[MUL_OVERFLOW4:%.*]] = extractvalue { i64, i1 } [[MUL2]], 1 @@ -39,7 +38,7 @@ ; LV-NEXT: [[TMP12:%.*]] = getelementptr i8, i8* [[A5]], i64 [[MUL_RESULT3]] ; LV-NEXT: [[TMP15:%.*]] = icmp ult i8* [[TMP12]], [[A5]] ; LV-NEXT: [[TMP17:%.*]] = or i1 [[TMP15]], [[MUL_OVERFLOW4]] -; LV-NEXT: [[TMP18:%.*]] = or i1 [[TMP8]], [[TMP17]] +; LV-NEXT: [[TMP18:%.*]] = or i1 [[TMP7]], [[TMP17]] ; LV-NEXT: br i1 [[TMP18]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH:%.*]] ; LV: for.body.ph.lver.orig: ; LV-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]]