diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h --- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h +++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h @@ -33,13 +33,13 @@ /// values. Also applies target-specific constant folding when not using /// InstructionSimplify. class InstSimplifyFolder final : public IRBuilderFolder { - const DataLayout &DL; TargetFolder ConstFolder; + SimplifyQuery SQ; virtual void anchor(); public: - InstSimplifyFolder(const DataLayout &DL) : DL(DL), ConstFolder(DL) {} + InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {} //===--------------------------------------------------------------------===// // Value-based folders. @@ -47,18 +47,19 @@ // Return an existing value or a constant if the operation can be simplified. // Otherwise return nullptr. //===--------------------------------------------------------------------===// + Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return SimplifyAddInst(LHS, RHS, HasNUW, HasNSW, SQ); + } + Value *FoldOr(Value *LHS, Value *RHS) const override { - return SimplifyOrInst(LHS, RHS, SimplifyQuery(DL)); + return SimplifyOrInst(LHS, RHS, SQ); } //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// - Value *CreateAdd(Constant *LHS, Constant *RHS, bool HasNUW = false, - bool HasNSW = false) const override { - return ConstFolder.CreateAdd(LHS, RHS, HasNUW, HasNSW); - } Value *CreateFAdd(Constant *LHS, Constant *RHS) const override { return ConstFolder.CreateFAdd(LHS, RHS); } 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 @@ -48,6 +48,15 @@ // Return an existing value or a constant if the operation can be simplified. // Otherwise return nullptr. //===--------------------------------------------------------------------===// + Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return Fold(ConstantExpr::getAdd(LC, RC, HasNUW, HasNSW)); + return nullptr; + } + Value *FoldOr(Value *LHS, Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(RHS); @@ -60,10 +69,6 @@ // Binary Operators //===--------------------------------------------------------------------===// - Constant *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const override { - return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW)); - } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override { return Fold(ConstantExpr::getFAdd(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 @@ -37,6 +37,15 @@ // Return an existing value or a constant if the operation can be simplified. // Otherwise return nullptr. //===--------------------------------------------------------------------===// + Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return ConstantExpr::getAdd(LC, RC, HasNUW, HasNSW); + return nullptr; + } + Value *FoldOr(Value *LHS, Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(RHS); @@ -49,11 +58,6 @@ // Binary Operators //===--------------------------------------------------------------------===// - Constant *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const override { - return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW); - } - Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override { return ConstantExpr::getFAdd(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 @@ -1211,9 +1211,8 @@ public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { - if (auto *LC = dyn_cast(LHS)) - if (auto *RC = dyn_cast(RHS)) - return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); + if (auto *V = Folder.FoldAdd(LHS, RHS, HasNUW, HasNSW)) + return V; return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, HasNUW, HasNSW); } 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 @@ -31,14 +31,14 @@ // Return an existing value or a constant if the operation can be simplified. // Otherwise return nullptr. //===--------------------------------------------------------------------===// + virtual Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, + bool HasNSW = false) const = 0; virtual Value *FoldOr(Value *LHS, Value *RHS) const = 0; //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// - virtual Value *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const = 0; virtual Value *CreateFAdd(Constant *LHS, Constant *RHS) const = 0; virtual Value *CreateSub(Constant *LHS, Constant *RHS, bool HasNUW = false, bool HasNSW = false) 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 @@ -43,21 +43,17 @@ // Return an existing value or a constant if the operation can be simplified. // Otherwise return nullptr. //===--------------------------------------------------------------------===// + Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, + bool HasNSW = false) const override { + return nullptr; + } + Value *FoldOr(Value *LHS, Value *RHS) const override { return nullptr; } //===--------------------------------------------------------------------===// // Binary Operators //===--------------------------------------------------------------------===// - Instruction *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, - bool HasNSW = false) const override { - BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override { return BinaryOperator::CreateFAdd(LHS, RHS); } diff --git a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-complex.ll b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-complex.ll --- a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-complex.ll +++ b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-complex.ll @@ -645,8 +645,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 -; CHECK-NEXT: [[TMP1:%.*]] = add i32 0, [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP4]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[UMAX1]], 4 @@ -730,8 +729,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 -; CHECK-NEXT: [[TMP1:%.*]] = add i32 0, [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP4]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[UMAX1]], 4 diff --git a/llvm/test/Transforms/LoopVectorize/induction.ll b/llvm/test/Transforms/LoopVectorize/induction.ll --- a/llvm/test/Transforms/LoopVectorize/induction.ll +++ b/llvm/test/Transforms/LoopVectorize/induction.ll @@ -4609,8 +4609,7 @@ ; CHECK: vector.scevcheck: ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[K]], -1 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP1]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP2]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP1]], 0 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]] ; CHECK-NEXT: br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] @@ -4746,8 +4745,7 @@ ; UNROLL-NO-IC: vector.scevcheck: ; UNROLL-NO-IC-NEXT: [[TMP0:%.*]] = add i64 [[K]], -1 ; UNROLL-NO-IC-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 -; UNROLL-NO-IC-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP1]] -; UNROLL-NO-IC-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP2]], 0 +; UNROLL-NO-IC-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP1]], 0 ; UNROLL-NO-IC-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 ; UNROLL-NO-IC-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]] ; UNROLL-NO-IC-NEXT: br i1 [[TMP8]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] @@ -6517,9 +6515,8 @@ ; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[TMP4]], i8 [[TMP5]]) ; CHECK-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i8, i1 } [[MUL]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = add i8 0, [[MUL_RESULT]] ; CHECK-NEXT: [[TMP7:%.*]] = sub i8 0, [[MUL_RESULT]] -; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i8 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i8 [[MUL_RESULT]], 0 ; CHECK-NEXT: [[TMP9:%.*]] = icmp sgt i8 [[TMP7]], 0 ; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[TMP3]], i1 [[TMP9]], i1 [[TMP8]] ; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP10]], [[MUL_OVERFLOW]] @@ -6748,9 +6745,8 @@ ; UNROLL-NO-IC-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[TMP4]], i8 [[TMP5]]) ; UNROLL-NO-IC-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0 ; UNROLL-NO-IC-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i8, i1 } [[MUL]], 1 -; UNROLL-NO-IC-NEXT: [[TMP6:%.*]] = add i8 0, [[MUL_RESULT]] ; UNROLL-NO-IC-NEXT: [[TMP7:%.*]] = sub i8 0, [[MUL_RESULT]] -; UNROLL-NO-IC-NEXT: [[TMP8:%.*]] = icmp slt i8 [[TMP6]], 0 +; UNROLL-NO-IC-NEXT: [[TMP8:%.*]] = icmp slt i8 [[MUL_RESULT]], 0 ; UNROLL-NO-IC-NEXT: [[TMP9:%.*]] = icmp sgt i8 [[TMP7]], 0 ; UNROLL-NO-IC-NEXT: [[TMP10:%.*]] = select i1 [[TMP3]], i1 [[TMP9]], i1 [[TMP8]] ; UNROLL-NO-IC-NEXT: [[TMP14:%.*]] = or i1 [[TMP10]], [[MUL_OVERFLOW]] diff --git a/llvm/test/Transforms/LoopVectorize/pr30654-phiscev-sext-trunc.ll b/llvm/test/Transforms/LoopVectorize/pr30654-phiscev-sext-trunc.ll --- a/llvm/test/Transforms/LoopVectorize/pr30654-phiscev-sext-trunc.ll +++ b/llvm/test/Transforms/LoopVectorize/pr30654-phiscev-sext-trunc.ll @@ -51,9 +51,8 @@ ; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[TMP4]], i8 [[TMP5]]) ; CHECK-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i8, i1 } [[MUL]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = add i8 0, [[MUL_RESULT]] ; CHECK-NEXT: [[TMP7:%.*]] = sub i8 0, [[MUL_RESULT]] -; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i8 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i8 [[MUL_RESULT]], 0 ; CHECK-NEXT: [[TMP9:%.*]] = icmp sgt i8 [[TMP7]], 0 ; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[TMP3]], i1 [[TMP9]], i1 [[TMP8]] ; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP10]], [[MUL_OVERFLOW]] @@ -177,9 +176,8 @@ ; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[TMP4]], i8 [[TMP5]]) ; CHECK-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i8, i1 } [[MUL]], 1 -; CHECK-NEXT: [[TMP6:%.*]] = add i8 0, [[MUL_RESULT]] ; CHECK-NEXT: [[TMP7:%.*]] = sub i8 0, [[MUL_RESULT]] -; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i8 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i8 [[MUL_RESULT]], 0 ; CHECK-NEXT: [[TMP9:%.*]] = icmp ugt i8 [[TMP7]], 0 ; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[TMP3]], i1 [[TMP9]], i1 [[TMP8]] ; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP10]], [[MUL_OVERFLOW]] @@ -377,9 +375,8 @@ ; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[TMP3]], i8 [[TMP4]]) ; CHECK-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0 ; CHECK-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i8, i1 } [[MUL]], 1 -; CHECK-NEXT: [[TMP5:%.*]] = add i8 0, [[MUL_RESULT]] ; CHECK-NEXT: [[TMP6:%.*]] = sub i8 0, [[MUL_RESULT]] -; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i8 [[TMP5]], 0 +; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i8 [[MUL_RESULT]], 0 ; CHECK-NEXT: [[TMP8:%.*]] = icmp sgt i8 [[TMP6]], 0 ; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[TMP2]], i1 [[TMP8]], i1 [[TMP7]] ; CHECK-NEXT: [[TMP13:%.*]] = or i1 [[TMP9]], [[MUL_OVERFLOW]] 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 @@ -255,8 +255,7 @@ ; LV-NEXT: [[MUL1:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[TMP1]]) ; LV-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i32, i1 } [[MUL1]], 0 ; LV-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i32, i1 } [[MUL1]], 1 -; LV-NEXT: [[TMP2:%.*]] = add i32 0, [[MUL_RESULT]] -; LV-NEXT: [[TMP5:%.*]] = icmp slt i32 [[TMP2]], 0 +; LV-NEXT: [[TMP5:%.*]] = icmp slt i32 [[MUL_RESULT]], 0 ; LV-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[MUL_OVERFLOW]] ; LV-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295 ; LV-NEXT: [[TMP9:%.*]] = or i1 [[TMP8]], [[TMP7]]