[IR] `IRBuilderBase::CreateAnd()`: fix short-circuiting for constant on LHS

Refs. https://reviews.llvm.org/D109368#3089809
This commit is contained in:
Roman Lebedev 2021-10-27 17:04:07 +03:00
parent f3df87d57e
commit 749581d21f
No known key found for this signature in database
GPG Key ID: 083C3EBB4A1689E0
10 changed files with 32 additions and 36 deletions

View File

@ -9,7 +9,7 @@
// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vadc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0)
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 1
// CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 29
// CHECK-NEXT: [[TMP3:%.*]] = and i32 1, [[TMP2]]
// CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1
// CHECK-NEXT: store i32 [[TMP3]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP4]]
@ -30,7 +30,7 @@ int32x4_t test_vadciq_s32(int32x4_t a, int32x4_t b, unsigned *carry_out)
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vadc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -51,7 +51,7 @@ uint32x4_t test_vadcq_u32(uint32x4_t a, uint32x4_t b, unsigned *carry)
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vadc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -74,7 +74,7 @@ uint32x4_t test_vadciq_m_u32(uint32x4_t inactive, uint32x4_t a, uint32x4_t b, un
// CHECK-NEXT: [[TMP4:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vadc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]], <4 x i1> [[TMP3]])
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 1
// CHECK-NEXT: [[TMP6:%.*]] = lshr i32 [[TMP5]], 29
// CHECK-NEXT: [[TMP7:%.*]] = and i32 1, [[TMP6]]
// CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], 1
// CHECK-NEXT: store i32 [[TMP7]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP8]]
@ -93,7 +93,7 @@ int32x4_t test_vadcq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, unsigne
// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0)
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 1
// CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 29
// CHECK-NEXT: [[TMP3:%.*]] = and i32 1, [[TMP2]]
// CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1
// CHECK-NEXT: store i32 [[TMP3]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP4]]
@ -111,7 +111,7 @@ int32x4_t test_vsbciq_s32(int32x4_t a, int32x4_t b, unsigned *carry_out) {
// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0)
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 1
// CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 29
// CHECK-NEXT: [[TMP3:%.*]] = and i32 1, [[TMP2]]
// CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1
// CHECK-NEXT: store i32 [[TMP3]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP4]]
@ -131,7 +131,7 @@ uint32x4_t test_vsbciq_u32(uint32x4_t a, uint32x4_t b, unsigned *carry_out) {
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -151,7 +151,7 @@ int32x4_t test_vsbcq_s32(int32x4_t a, int32x4_t b, unsigned *carry) {
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -171,7 +171,7 @@ uint32x4_t test_vsbcq_u32(uint32x4_t a, uint32x4_t b, unsigned *carry) {
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -191,7 +191,7 @@ int32x4_t test_vsbciq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, unsign
// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]])
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1
// CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29
// CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]]
// CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
// CHECK-NEXT: store i32 [[TMP5]], i32* [[CARRY_OUT:%.*]], align 4
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP6]]
@ -213,7 +213,7 @@ uint32x4_t test_vsbciq_m_u32(uint32x4_t inactive, uint32x4_t a, uint32x4_t b, un
// CHECK-NEXT: [[TMP4:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]], <4 x i1> [[TMP3]])
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 1
// CHECK-NEXT: [[TMP6:%.*]] = lshr i32 [[TMP5]], 29
// CHECK-NEXT: [[TMP7:%.*]] = and i32 1, [[TMP6]]
// CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], 1
// CHECK-NEXT: store i32 [[TMP7]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP8]]
@ -235,7 +235,7 @@ int32x4_t test_vsbcq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, unsigne
// CHECK-NEXT: [[TMP4:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 [[TMP1]], <4 x i1> [[TMP3]])
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 1
// CHECK-NEXT: [[TMP6:%.*]] = lshr i32 [[TMP5]], 29
// CHECK-NEXT: [[TMP7:%.*]] = and i32 1, [[TMP6]]
// CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], 1
// CHECK-NEXT: store i32 [[TMP7]], i32* [[CARRY]], align 4
// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP4]], 0
// CHECK-NEXT: ret <4 x i32> [[TMP8]]

View File

@ -172,7 +172,7 @@ char *nullptr_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 0, %[[COMPUTED_OFFSET]], !nosanitize
// CHECK-SANITIZE-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 false, %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[COMPUTED_GEP_IS_NOT_NULL]], false, !nosanitize
// CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 false, %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[COMPUTED_OFFSET_OVERFLOWED]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], 0, !nosanitize
@ -258,7 +258,7 @@ char *one_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 1, %[[COMPUTED_OFFSET]], !nosanitize
// CHECK-SANITIZE-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 icmp ne (i8* inttoptr (i64 1 to i8*), i8* null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[COMPUTED_GEP_IS_NOT_NULL]], icmp ne (i8* inttoptr (i64 1 to i8*), i8* null), !nosanitize
// CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (i8* inttoptr (i64 1 to i8*), i8* null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[COMPUTED_OFFSET_OVERFLOWED]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], 1, !nosanitize
@ -344,7 +344,7 @@ char *allones_var(unsigned long offset) {
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET:.*]] = extractvalue { i64, i1 } %[[COMPUTED_OFFSET_AGGREGATE]], 0, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP:.*]] = add i64 -1, %[[COMPUTED_OFFSET]], !nosanitize
// CHECK-SANITIZE-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 icmp ne (i8* inttoptr (i64 -1 to i8*), i8* null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-C-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = and i1 %[[COMPUTED_GEP_IS_NOT_NULL]], icmp ne (i8* inttoptr (i64 -1 to i8*), i8* null), !nosanitize
// CHECK-SANITIZE-CPP-NEXT: %[[BOTH_POINTERS_ARE_NULL_OR_BOTH_ARE_NONNULL:.*]] = icmp eq i1 icmp ne (i8* inttoptr (i64 -1 to i8*), i8* null), %[[COMPUTED_GEP_IS_NOT_NULL]], !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_OFFSET_DID_NOT_OVERFLOW:.*]] = xor i1 %[[COMPUTED_OFFSET_OVERFLOWED]], true, !nosanitize
// CHECK-SANITIZE-NEXT: %[[COMPUTED_GEP_IS_UGE_BASE:.*]] = icmp uge i64 %[[COMPUTED_GEP]], -1, !nosanitize

View File

@ -198,7 +198,7 @@ void OneScalarOp() {
// CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
// CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
// CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], <i32 -1, i32 -1, i32 -1, i32 -1>
// CHECK: [[RHS_AND:%.+]] = and <4 x i32> <i32 5, i32 5, i32 5, i32 5>, [[XOR]]
// CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[XOR]], <i32 5, i32 5, i32 5, i32 5>
// CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS]], [[SEXT]]
// CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
@ -224,7 +224,7 @@ void OneScalarOp() {
// CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
// CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], <i64 -1, i64 -1, i64 -1, i64 -1>
// CHECK: [[LHS_CAST:%.+]] = bitcast <4 x double> [[LHS]] to <4 x i64>
// CHECK: [[RHS_AND:%.+]] = and <4 x i64> <i64 4618441417868443648, i64 4618441417868443648, i64 4618441417868443648, i64 4618441417868443648>, [[XOR]]
// CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[XOR]], <i64 4618441417868443648, i64 4618441417868443648, i64 4618441417868443648, i64 4618441417868443648>
// CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS_CAST]], [[SEXT]]
// CHECK: = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
@ -234,7 +234,7 @@ void OneScalarOp() {
// CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
// CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
// CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], <i64 -1, i64 -1, i64 -1, i64 -1>
// CHECK: [[RHS_AND:%.+]] = and <4 x i64> <i64 6, i64 6, i64 6, i64 6>, [[XOR]]
// CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[XOR]], <i64 6, i64 6, i64 6, i64 6>
// CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]]
// CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]]

View File

@ -102,9 +102,8 @@ int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
int *arg4,
int arg5, ...) {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
// CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[ARG1CMP]], [[ARG2CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_3:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK_2]]
@ -128,10 +127,9 @@ int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
// CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[ARG1CMP]]
// CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
// CHECK: [[NULL]]:
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
@ -145,10 +143,9 @@ int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
// CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
// CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
// CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
// CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
// CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[ARG1CMP]]
// CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
// CHECK: [[NULL]]:
// CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize

View File

@ -1360,6 +1360,8 @@ public:
}
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (!isa<Constant>(RHS) && isa<Constant>(LHS))
std::swap(LHS, RHS);
if (auto *RC = dyn_cast<Constant>(RHS)) {
if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isMinusOne())
return LHS; // LHS & -1 -> LHS

View File

@ -714,7 +714,7 @@ define void @p10_x_is_not_one(i32 %bit, i32* %p0, i32* %p1) {
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], metadata [[META166:![0-9]+]], metadata !DIExpression()), !dbg [[DBG171]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, !dbg [[DBG172:![0-9]+]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], !dbg [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED:%.*]] = and i32 2, [[BIT_MASK]], !dbg [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED:%.*]] = and i32 [[BIT_MASK]], 2, !dbg [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[DOTMASKED]], i1 true), !dbg [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_NUMACTIVEBITS:%.*]] = sub nuw nsw i32 32, [[DOTMASKED_NUMLEADINGZEROS]], !dbg [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_LEADINGONEPOS:%.*]] = add nsw i32 [[DOTMASKED_NUMACTIVEBITS]], -1, !dbg [[DBG172]]

View File

@ -232,12 +232,11 @@ define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %l
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP0]], i32 9) [ "deopt"() ]
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4

View File

@ -282,14 +282,13 @@ define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %l
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
; CHECK-NEXT: br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[WIDENABLE_COND]]
; CHECK-NEXT: br i1 [[TMP1]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
; CHECK: deopt:
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
; CHECK-NEXT: ret i32 [[DEOPTCALL]]

View File

@ -385,14 +385,13 @@ define i32 @constant_length(i32* %array, i32 %n) {
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
; CHECK: loop.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], 20
; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
; CHECK-NEXT: [[UNKNOWN:%.*]] = load volatile i1, i1* @UNKNOWN, align 1
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[UNKNOWN]]) [ "deopt"() ]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP0]], i32 9) [ "deopt"() ]
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4

View File

@ -136,8 +136,8 @@ define i1 @inline5(i8* %p) {
; CHECK-NEXT: [[trunc:%.*]] = trunc i64 [[or]] to i32
; CHECK-NEXT: [[and:%.*]] = and i32 [[trunc]], 31
; CHECK-NEXT: [[shl2:%.*]] = shl i32 1, [[and]]
; X86-NEXT: [[and2:%.*]] = and i32 ptrtoint ([0 x i8]* @__typeid_inline5_inline_bits to i32), [[shl2]]
; ARM-NEXT: [[and2:%.*]] = and i32 123, [[shl2]]
; X86-NEXT: [[and2:%.*]] = and i32 [[shl2]], ptrtoint ([0 x i8]* @__typeid_inline5_inline_bits to i32)
; ARM-NEXT: [[and2:%.*]] = and i32 [[shl2]], 123
; CHECK-NEXT: [[ne:%.*]] = icmp ne i32 [[and2]], 0
; CHECK-NEXT: br label %[[f]]
@ -164,8 +164,8 @@ define i1 @inline6(i8* %p) {
; CHECK: [[t]]:
; CHECK-NEXT: [[and:%.*]] = and i64 [[or]], 63
; CHECK-NEXT: [[shl2:%.*]] = shl i64 1, [[and]]
; X86-NEXT: [[and2:%.*]] = and i64 ptrtoint ([0 x i8]* @__typeid_inline6_inline_bits to i64), [[shl2]]
; ARM-NEXT: [[and2:%.*]] = and i64 1000000000000, [[shl2]]
; X86-NEXT: [[and2:%.*]] = and i64 [[shl2]], ptrtoint ([0 x i8]* @__typeid_inline6_inline_bits to i64)
; ARM-NEXT: [[and2:%.*]] = and i64 [[shl2]], 1000000000000
; CHECK-NEXT: [[ne:%.*]] = icmp ne i64 [[and2]], 0
; CHECK-NEXT: br label %[[f]]