diff --git a/llvm/test/Transforms/IndVarSimplify/X86/widening-vs-and-elimination.ll b/llvm/test/Transforms/IndVarSimplify/X86/widening-vs-and-elimination.ll index cef5024beb8809..fad21e9938c19c 100644 --- a/llvm/test/Transforms/IndVarSimplify/X86/widening-vs-and-elimination.ll +++ b/llvm/test/Transforms/IndVarSimplify/X86/widening-vs-and-elimination.ll @@ -60,3 +60,82 @@ backedge: ; preds = %loop exit: ; preds = %loop ret void } + +define i32 @test_02(i32 %start, i32 %limit) { +; WIDENING_ON-LABEL: @test_02( +; WIDENING_ON-NEXT: bb: +; WIDENING_ON-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; WIDENING_ON-NEXT: br label [[LOOP:%.*]] +; WIDENING_ON: loop: +; WIDENING_ON-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[BB:%.*]] ] +; WIDENING_ON-NEXT: [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[BB]] ] +; WIDENING_ON-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635 +; WIDENING_ON-NEXT: br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]] +; WIDENING_ON: checked: +; WIDENING_ON-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1 +; WIDENING_ON-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 +; WIDENING_ON-NEXT: [[NOT_ZERO:%.*]] = icmp ne i64 [[INDVARS_IV]], 0 +; WIDENING_ON-NEXT: [[TMP2:%.*]] = zext i32 [[LIMIT:%.*]] to i64 +; WIDENING_ON-NEXT: [[RANGE_CHECK_WIDE:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]] +; WIDENING_ON-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_WIDE]] +; WIDENING_ON-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] +; WIDENING_ON: backedge: +; WIDENING_ON-NEXT: [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1 +; WIDENING_ON-NEXT: br label [[LOOP]] +; WIDENING_ON: exit: +; WIDENING_ON-NEXT: ret i32 0 +; WIDENING_ON: failed: +; WIDENING_ON-NEXT: ret i32 1 +; +; WIDENING_OFF-LABEL: @test_02( +; WIDENING_OFF-NEXT: bb: +; WIDENING_OFF-NEXT: br label [[LOOP:%.*]] +; WIDENING_OFF: loop: +; WIDENING_OFF-NEXT: [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[BB:%.*]] ] +; WIDENING_OFF-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ [[START:%.*]], [[BB]] ] +; WIDENING_OFF-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635 +; WIDENING_OFF-NEXT: br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]] +; WIDENING_OFF: checked: +; WIDENING_OFF-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 +; WIDENING_OFF-NEXT: [[NOT_ZERO:%.*]] = icmp ne i32 [[IV]], 0 +; WIDENING_OFF-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[LIMIT:%.*]] +; WIDENING_OFF-NEXT: [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK]] +; WIDENING_OFF-NEXT: br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]] +; WIDENING_OFF: backedge: +; WIDENING_OFF-NEXT: [[ZEXT:%.*]] = zext i32 [[IV_NEXT]] to i64 +; WIDENING_OFF-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) poison, i64 [[ZEXT]] +; WIDENING_OFF-NEXT: [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1 +; WIDENING_OFF-NEXT: br label [[LOOP]] +; WIDENING_OFF: exit: +; WIDENING_OFF-NEXT: ret i32 0 +; WIDENING_OFF: failed: +; WIDENING_OFF-NEXT: ret i32 1 +; +bb: + br label %loop + +loop: ; preds = %backedge, %bb + %canonical_iv = phi i32 [ %canonical_iv.next, %backedge ], [ 0, %bb ] + %iv = phi i32 [ %iv.next, %backedge ], [ %start, %bb ] + %canonical_iv_check = icmp ult i32 %canonical_iv, 65635 + br i1 %canonical_iv_check, label %checked, label %failed + +checked: + %iv.next = add i32 %iv, -1 + %not.zero = icmp ne i32 %iv, 0 + %range.check = icmp ult i32 %iv.next, %limit + %and = and i1 %not.zero, %range.check + br i1 %and, label %backedge, label %exit + +backedge: ; preds = %loop + %zext = zext i32 %iv.next to i64 + %gep = getelementptr inbounds i32, ptr addrspace(1) poison, i64 %zext + %canonical_iv.next = add i32 %canonical_iv, 1 + br label %loop + +exit: ; preds = %loop + ret i32 0 + +failed: + ret i32 1 +}