diff --git a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll index 816c7ae912a182..88bb43576a4e17 100644 --- a/llvm/test/Transforms/ConstraintElimination/add-nsw.ll +++ b/llvm/test/Transforms/ConstraintElimination/add-nsw.ll @@ -767,3 +767,156 @@ entry: %c = icmp ult i8 %add.off.2, %high ret i1 %c } + +define i1 @add_neg_1_known_sge_ult_1(i32 %a) { +; CHECK-LABEL: @add_neg_1_known_sge_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 1 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -1 + %c = icmp ult i32 %sub, %a + ret i1 %c +} + +define i1 @add_neg_1_known_sge_uge_1(i32 %a) { +; CHECK-LABEL: @add_neg_1_known_sge_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 +; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[SUB]], 0 +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 1 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -1 + %c = icmp uge i32 %sub, 0 + ret i1 %c +} + +define i1 @add_neg_1_not_known_sge_ult_1(i32 %a) { +; CHECK-LABEL: @add_neg_1_not_known_sge_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 0 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -1 + %c = icmp ult i32 %sub, %a + ret i1 %c +} + +define i1 @add_neg_1_not_known_sge_uge_1(i32 %a) { +; CHECK-LABEL: @add_neg_1_not_known_sge_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 +; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[SUB]], 0 +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 0 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -1 + %c = icmp uge i32 %sub, 0 + ret i1 %c +} + +define i1 @add_neg_3_known_sge_ult_1(i32 %a) { +; CHECK-LABEL: @add_neg_3_known_sge_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 3 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 3 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -3 + %c = icmp ult i32 %sub, %a + ret i1 %c +} + +define i1 @add_neg_3_known_sge_uge_1(i32 %a) { +; CHECK-LABEL: @add_neg_3_known_sge_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 4 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 +; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[SUB]], 0 +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 4 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -3 + %c = icmp uge i32 %sub, 0 + ret i1 %c +} + +define i1 @add_neg_3_not_known_sge_ult_1(i32 %a) { +; CHECK-LABEL: @add_neg_3_not_known_sge_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 2 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -3 + %c = icmp ult i32 %sub, %a + ret i1 %c +} + +define i1 @add_neg_3_not_known_sge_uge_1(i32 %a) { +; CHECK-LABEL: @add_neg_3_not_known_sge_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 +; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[SUB]], 0 +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, 2 + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -3 + %c = icmp uge i32 %sub, 0 + ret i1 %c +} + +define i1 @add_neg_3_not_known_sge_ult_2(i32 %a, i32 %b) { +; CHECK-LABEL: @add_neg_3_not_known_sge_ult_2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %a.sge = icmp sge i32 %a, %b + call void @llvm.assume(i1 %a.sge) + %sub = add nsw i32 %a, -3 + %c = icmp ult i32 %sub, %a + ret i1 %c +} diff --git a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-add.ll b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-add.ll index cc980cda77ec69..c56ca5af4c253a 100644 --- a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-add.ll +++ b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-add.ll @@ -385,3 +385,104 @@ ptr.check: exit: ret i4 3 } + +define i1 @gep_count_add_1_sge_known_ult_1(i32 %count, ptr %p) { +; CHECK-LABEL: @gep_count_add_1_sge_known_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[SGE]]) +; CHECK-NEXT: [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64 +; CHECK-NEXT: [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]] +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[COUNT]], -1 +; CHECK-NEXT: [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64 +; CHECK-NEXT: [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]] +; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %sge = icmp sge i32 %count, 1 + call void @llvm.assume(i1 %sge) + %count.ext = zext i32 %count to i64 + %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext + %sub = add nsw i32 %count, -1 + %sub.ext = zext i32 %sub to i64 + %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext + %c = icmp ult ptr %gep.sub, %gep.count + ;%2 = icmp uge ptr %0, %p + ret i1 %c +} + +define i1 @gep_count_add_1_sge_known_uge_1(i32 %count, ptr %p) { +; CHECK-LABEL: @gep_count_add_1_sge_known_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[SGE]]) +; CHECK-NEXT: [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64 +; CHECK-NEXT: [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]] +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[COUNT]], -1 +; CHECK-NEXT: [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64 +; CHECK-NEXT: [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]] +; CHECK-NEXT: [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %sge = icmp sge i32 %count, 1 + call void @llvm.assume(i1 %sge) + %count.ext = zext i32 %count to i64 + %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext + %sub = add nsw i32 %count, -1 + %sub.ext = zext i32 %sub to i64 + %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext + %c = icmp uge ptr %gep.sub, %p + ret i1 %c +} + +define i1 @gep_count_add_2_sge_not_known_ult_1(i32 %count, ptr %p) { +; CHECK-LABEL: @gep_count_add_2_sge_not_known_ult_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[SGE]]) +; CHECK-NEXT: [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64 +; CHECK-NEXT: [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]] +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[COUNT]], -2 +; CHECK-NEXT: [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64 +; CHECK-NEXT: [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]] +; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %sge = icmp sge i32 %count, 1 + call void @llvm.assume(i1 %sge) + %count.ext = zext i32 %count to i64 + %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext + %sub = add nsw i32 %count, -2 + %sub.ext = zext i32 %sub to i64 + %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext + %c = icmp ult ptr %gep.sub, %gep.count + ret i1 %c +} + +define i1 @gep_count_add_2_sge_not_known_uge_1(i32 %count, ptr %p) { +; CHECK-LABEL: @gep_count_add_2_sge_not_known_uge_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1 +; CHECK-NEXT: call void @llvm.assume(i1 [[SGE]]) +; CHECK-NEXT: [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64 +; CHECK-NEXT: [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]] +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[COUNT]], -2 +; CHECK-NEXT: [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64 +; CHECK-NEXT: [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]] +; CHECK-NEXT: [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]] +; CHECK-NEXT: ret i1 [[C]] +; +entry: + %sge = icmp sge i32 %count, 1 + call void @llvm.assume(i1 %sge) + %count.ext = zext i32 %count to i64 + %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext + %sub = add nsw i32 %count, -2 + %sub.ext = zext i32 %sub to i64 + %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext + %c = icmp uge ptr %gep.sub, %p + ret i1 %c +}