diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c --- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c +++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c @@ -89,7 +89,8 @@ // CHECK-SANITIZE-C-NEXT: %[[COMPUTED_GEP_IS_NOT_NULL:.*]] = icmp ne i64 %[[COMPUTED_GEP]], 0, !nosanitize // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-C-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-C-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_UGE_BASE]], !nosanitize + // CHECK-SANITIZE-C-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-C-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-C-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_200]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) @@ -117,7 +118,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_UGE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_300]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) @@ -145,7 +147,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_UGE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_400]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) diff --git a/clang/test/CodeGen/catch-pointer-overflow.c b/clang/test/CodeGen/catch-pointer-overflow.c --- a/clang/test/CodeGen/catch-pointer-overflow.c +++ b/clang/test/CodeGen/catch-pointer-overflow.c @@ -187,7 +187,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_UGE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_500]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) @@ -217,7 +218,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_ULE_BASE:.*]] = icmp ule i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_ULE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_600]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) @@ -247,7 +249,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_UGE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_700]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) @@ -277,7 +280,8 @@ // CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 %[[BASE_IS_NOT_NULLPTR]], %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize // CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_ULE_BASE:.*]] = icmp ule i64 %[[COMPUTED_GEP]], %[[BASE_RELOADED_INT]], !nosanitize - // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[COMPUTED_GEP_IS_ULE_BASE]], !nosanitize + // CHECK-SANITIZE-NEXT: %[[AND_TRUE:.*]] = and i1 %[[COMPUTED_GEP_IS_UGE_BASE]], true, !nosanitize + // CHECK-SANITIZE-NEXT: %[[GEP_IS_OKAY:.*]] = and i1 %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL]], %[[AND_TRUE]], !nosanitize // CHECK-SANITIZE-NEXT: br i1 %[[GEP_IS_OKAY]], label %[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize // CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]: // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(i8* bitcast ({ {{{.*}}} }* @[[LINE_800]] to i8*), i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]]) diff --git a/clang/test/CodeGen/cmse-clear-return.c b/clang/test/CodeGen/cmse-clear-return.c --- a/clang/test/CodeGen/cmse-clear-return.c +++ b/clang/test/CodeGen/cmse-clear-return.c @@ -229,8 +229,10 @@ T14 t14; __attribute__((cmse_nonsecure_entry)) T14 f14() { return t14; } // CHECK: define {{.*}} @f14() -// CHECK: %[[R:.*]] = load -// CHECK: ret i32 %[[R]] +// CHECK: [[R:%.*]] = load +// CHECK-LE-NOPT-NEXT: [[AND:%.+]] = and i32 [[R]], -1 +// CHECK-BE-NOPT-NEXT: [[AND:%.+]] = and i32 [[R]], -1 +// CHECK_NEXT: ret i32 [[AND]] // LE: 1111..11 1111..11 11111111 11111111 0xfffff3f3/-3085 // BE: 11..1111 11..1111 11111111 11111111 0xcfcfffff/-808452097 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 @@ -52,6 +52,10 @@ return SimplifyAddInst(LHS, RHS, HasNUW, HasNSW, SQ); } + Value *FoldAnd(Value *LHS, Value *RHS) const override { + return SimplifyAndInst(LHS, RHS, SQ); + } + Value *FoldOr(Value *LHS, Value *RHS) const override { return SimplifyOrInst(LHS, RHS, SQ); } @@ -122,9 +126,6 @@ bool isExact = false) const override { return ConstFolder.CreateAShr(LHS, RHS, isExact); } - Value *CreateAnd(Constant *LHS, Constant *RHS) const override { - return ConstFolder.CreateAnd(LHS, RHS); - } Value *CreateXor(Constant *LHS, Constant *RHS) const override { return ConstFolder.CreateXor(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 @@ -57,6 +57,14 @@ return nullptr; } + Value *FoldAnd(Value *LHS, Value *RHS) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return Fold(ConstantExpr::getAnd(LC, RC)); + return nullptr; + } + Value *FoldOr(Value *LHS, Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(RHS); @@ -150,9 +158,6 @@ bool isExact = false) const override { return Fold(ConstantExpr::getAShr(LHS, RHS, isExact)); } - Constant *CreateAnd(Constant *LHS, Constant *RHS) const override { - return Fold(ConstantExpr::getAnd(LHS, RHS)); - } 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 @@ -47,6 +47,14 @@ return nullptr; } + Value *FoldAnd(Value *LHS, Value *RHS) const override { + auto *LC = dyn_cast(LHS); + auto *RC = dyn_cast(RHS); + if (LC && RC) + return ConstantExpr::getAnd(LC, RC); + return nullptr; + } + Value *FoldOr(Value *LHS, Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(RHS); @@ -154,10 +162,6 @@ return ConstantExpr::getAShr(LHS, RHS, isExact); } - Constant *CreateAnd(Constant *LHS, Constant *RHS) const override { - return ConstantExpr::getAnd(LHS, RHS); - } - 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 @@ -1359,12 +1359,8 @@ } Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { - if (auto *RC = dyn_cast(RHS)) { - if (isa(RC) && cast(RC)->isMinusOne()) - return LHS; // LHS & -1 -> LHS - if (auto *LC = dyn_cast(LHS)) - return Insert(Folder.CreateAnd(LC, RC), Name); - } + if (auto *V = Folder.FoldAnd(LHS, RHS)) + return V; return Insert(BinaryOperator::CreateAnd(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 @@ -33,6 +33,9 @@ //===--------------------------------------------------------------------===// virtual Value *FoldAdd(Value *LHS, Value *RHS, bool HasNUW = false, bool HasNSW = false) const = 0; + + virtual Value *FoldAnd(Value *LHS, Value *RHS) const = 0; + virtual Value *FoldOr(Value *LHS, Value *RHS) const = 0; virtual Value *FoldICmp(CmpInst::Predicate P, Value *LHS, @@ -68,7 +71,6 @@ bool isExact = false) const = 0; virtual Value *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false) const = 0; - virtual Value *CreateAnd(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 @@ -48,6 +48,8 @@ return nullptr; } + Value *FoldAnd(Value *LHS, Value *RHS) const override { return nullptr; } + Value *FoldOr(Value *LHS, Value *RHS) const override { return nullptr; } Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override { @@ -149,10 +151,6 @@ return BinaryOperator::CreateExactAShr(LHS, RHS); } - Instruction *CreateAnd(Constant *LHS, Constant *RHS) const override { - return BinaryOperator::CreateAnd(LHS, RHS); - } - Instruction *CreateXor(Constant *LHS, Constant *RHS) const override { return BinaryOperator::CreateXor(LHS, RHS); } diff --git a/llvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll b/llvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll --- a/llvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll +++ b/llvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll @@ -581,10 +581,11 @@ define void @p8_constant_mask_signbit_noncanonical(i32 %x, i32* %p0, i32* %p1) { ; LZCNT-LABEL: @p8_constant_mask_signbit_noncanonical( ; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), !dbg [[DBG142:![0-9]+]] -; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_NUMLEADINGZEROS]], !dbg [[DBG142]] -; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add nsw i32 [[X_NUMACTIVEBITS]], -1, !dbg [[DBG142]] -; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_LEADINGONEPOS]], !dbg [[DBG142]] +; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], -1, !dbg [[DBG142:![0-9]+]] +; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), !dbg [[DBG142]] +; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_MASKED_NUMLEADINGZEROS]], !dbg [[DBG142]] +; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add nsw i32 [[X_MASKED_NUMACTIVEBITS]], -1, !dbg [[DBG142]] +; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_MASKED_LEADINGONEPOS]], !dbg [[DBG142]] ; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, !dbg [[DBG142]] ; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], !dbg [[DBG142]] ; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, !dbg [[DBG142]] @@ -648,10 +649,11 @@ define void @p9_constant_mask_signbit_canonical(i32 %x, i32* %p0, i32* %p1) { ; LZCNT-LABEL: @p9_constant_mask_signbit_canonical( ; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), !dbg [[DBG156:![0-9]+]] -; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_NUMLEADINGZEROS]], !dbg [[DBG156]] -; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add nsw i32 [[X_NUMACTIVEBITS]], -1, !dbg [[DBG156]] -; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_LEADINGONEPOS]], !dbg [[DBG156]] +; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], -1, !dbg [[DBG156:![0-9]+]] +; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), !dbg [[DBG156]] +; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_MASKED_NUMLEADINGZEROS]], !dbg [[DBG156]] +; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add nsw i32 [[X_MASKED_NUMACTIVEBITS]], -1, !dbg [[DBG156]] +; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_MASKED_LEADINGONEPOS]], !dbg [[DBG156]] ; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, !dbg [[DBG156]] ; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], !dbg [[DBG156]] ; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, !dbg [[DBG156]] @@ -991,10 +993,11 @@ define i32 @p14(i32 %x) { ; LZCNT-LABEL: @p14( ; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), !dbg [[DBG231:![0-9]+]] -; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_NUMLEADINGZEROS]], !dbg [[DBG231]] -; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add nsw i32 [[X_NUMACTIVEBITS]], -1, !dbg [[DBG231]] -; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_LEADINGONEPOS]], !dbg [[DBG231]] +; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], -1, !dbg [[DBG231:![0-9]+]] +; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), !dbg [[DBG231]] +; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_MASKED_NUMLEADINGZEROS]], !dbg [[DBG231]] +; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add nsw i32 [[X_MASKED_NUMACTIVEBITS]], -1, !dbg [[DBG231]] +; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_MASKED_LEADINGONEPOS]], !dbg [[DBG231]] ; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, !dbg [[DBG231]] ; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], !dbg [[DBG231]] ; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, !dbg [[DBG231]] @@ -1615,10 +1618,11 @@ define i32 @n30(i32 %x) { ; LZCNT-LABEL: @n30( ; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), !dbg [[DBG462:![0-9]+]] -; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_NUMLEADINGZEROS]], !dbg [[DBG462]] -; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add nsw i32 [[X_NUMACTIVEBITS]], -1, !dbg [[DBG462]] -; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_LEADINGONEPOS]], !dbg [[DBG462]] +; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], -1, !dbg [[DBG462:![0-9]+]] +; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), !dbg [[DBG462]] +; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[X_MASKED_NUMLEADINGZEROS]], !dbg [[DBG462]] +; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add nsw i32 [[X_MASKED_NUMACTIVEBITS]], -1, !dbg [[DBG462]] +; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i32 31, [[X_MASKED_LEADINGONEPOS]], !dbg [[DBG462]] ; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, !dbg [[DBG462]] ; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], !dbg [[DBG462]] ; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, !dbg [[DBG462]] diff --git a/llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll b/llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll --- a/llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll +++ b/llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll @@ -17,12 +17,10 @@ ; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr [[STRUCT_FOO]], %struct.foo* @global, i64 0, i32 0, i64 [[TMP1]] ; CHECK-NEXT: [[SCEVGEP45:%.*]] = bitcast double* [[SCEVGEP4]] to i8* ; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* bitcast (%struct.foo* @global to i8*), [[SCEVGEP23]] -; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 false, [[BOUND1]] ; CHECK-NEXT: [[BOUND06:%.*]] = icmp ult i8* [[SCEVGEP1]], [[SCEVGEP45]] ; CHECK-NEXT: [[BOUND17:%.*]] = icmp ult i8* bitcast (double* getelementptr inbounds ([[STRUCT_FOO]], %struct.foo* @global, i64 0, i32 1, i64 0) to i8*), [[SCEVGEP23]] ; CHECK-NEXT: [[FOUND_CONFLICT8:%.*]] = and i1 [[BOUND06]], [[BOUND17]] -; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT8]] -; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label %loop.ph.lver.orig, label %loop.ph +; CHECK-NEXT: br i1 [[FOUND_CONFLICT8]], label %loop.ph.lver.orig, label %loop.ph ; entry: %N.ext = zext i32 %N to i64