Files
clang-p2996/llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll
Philip Reames 20cbb6cdf8 [LoopPred] Selectively disable to preserve test cases
I'm about to enable the new loop predication transform by default.  It has the effect of completely destroying many read only loops - which happen to be a super common idiom in our test cases.  So as to preserve test coverage of other transforms, disable the new transform where it would cause sharp test coverage regressions.

(This is semantically part of the enabling commit.  It's committed separate to ease revert if the actual flag flip gets reverted.)
2019-11-06 15:41:57 -08:00

661 lines
20 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -indvars -S -indvars-predicate-loops=0 < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; General case: without extra knowledge, trunc cannot be eliminated.
define void @test_00(i64 %start, i32 %n) {
;
; CHECK-LABEL: @test_00(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_01(i32 %n) {
;
; CHECK-LABEL: @test_01(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Max value at which we can eliminate trunc: SINT_MAX - 1.
define void @test_02(i32 %n) {
;
; CHECK-LABEL: @test_02(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 2147483646, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; If we start from SINT_MAX then the predicate is always false.
define void @test_03(i32 %n) {
;
; CHECK-LABEL: @test_03(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [2147483647, %entry], [%iv.next, %loop]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Minimum value at which we can apply the transform: SINT_MIN + 1.
define void @test_04(i32 %n) {
;
; CHECK-LABEL: @test_04(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -2147483647, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; FIXME: Harmful LFTR should be thrown away.
define void @test_05(i32 %n) {
;
; CHECK-LABEL: @test_05(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -2147483648, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1.
define void @test_06(i32 %n) {
;
; CHECK-LABEL: @test_06(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -2147483649, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; General case: without extra knowledge, trunc cannot be eliminated.
define void @test_00_unsigned(i64 %start, i32 %n) {
; CHECK-LABEL: @test_00_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; FIXME: Harmful LFTR should be thrown away.
define void @test_01_unsigned(i32 %n) {
; CHECK-LABEL: @test_01_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Max value at which we can eliminate trunc: UINT_MAX - 1.
define void @test_02_unsigned(i32 %n) {
; CHECK-LABEL: @test_02_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 4294967294, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; If we start from UINT_MAX then the predicate is always false.
define void @test_03_unsigned(i32 %n) {
; CHECK-LABEL: @test_03_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 4294967295, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Minimum value at which we can apply the transform: UINT_MIN.
define void @test_04_unsigned(i32 %n) {
; CHECK-LABEL: @test_04_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Start from 1.
define void @test_05_unsigned(i32 %n) {
; CHECK-LABEL: @test_05_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1.
define void @test_06_unsigned(i32 %n) {
; CHECK-LABEL: @test_06_unsigned(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -1, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ult i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Do not eliminate trunc if it is used by something different from icmp.
define void @test_07(i32* %p, i32 %n) {
; CHECK-LABEL: @test_07(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
; CHECK-NEXT: store i32 [[NARROW_IV]], i32* [[P:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
store i32 %narrow.iv, i32* %p
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Check that we can eliminate both signed and unsigned compare.
define void @test_08(i32 %n) {
; CHECK-LABEL: @test_08(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp1 = icmp slt i32 %narrow.iv, %n
%cmp2 = icmp ult i32 %narrow.iv, %n
%cmp = and i1 %cmp1, %cmp2
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Widen NE as unsigned.
define void @test_09(i32 %n) {
; CHECK-LABEL: @test_09(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ne i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
; Widen NE as signed.
define void @test_10(i32 %n) {
; CHECK-LABEL: @test_10(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[SEXT]]
; CHECK-NEXT: [[NEGCMP:%.*]] = icmp slt i64 [[IV]], -10
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[NEGCMP]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -100, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv to i32
%trunccmp = icmp ne i32 %narrow.iv, %n
%negcmp = icmp slt i64 %iv, -10
%cmp = and i1 %trunccmp, %negcmp
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_11() {
; CHECK-LABEL: @test_11(
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]]
; CHECK: bb2:
; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
; CHECK: bb3:
; CHECK-NEXT: br label [[BB4]]
; CHECK: bb4:
; CHECK-NEXT: br label [[BB6]]
; CHECK: bb5:
; CHECK-NEXT: [[_TMP24:%.*]] = icmp slt i16 undef, 0
; CHECK-NEXT: br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]]
; CHECK: bb6:
; CHECK-NEXT: br i1 false, label [[BB1]], label [[BB7:%.*]]
; CHECK: bb7:
; CHECK-NEXT: ret void
;
br label %bb1
bb1: ; preds = %bb6, %0
%e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
br i1 undef, label %bb2, label %bb6
bb2: ; preds = %bb1
%_tmp15 = trunc i32 %e.5.0 to i16
br i1 undef, label %bb3, label %bb4
bb3: ; preds = %bb2
br label %bb4
bb4: ; preds = %bb3, %bb2
br label %bb6
bb5: ; preds = %bb5, %bb5
%_tmp24 = icmp slt i16 %_tmp15, 0
br i1 %_tmp24, label %bb5, label %bb5
bb6: ; preds = %bb4, %bb1
%_tmp32 = add nuw nsw i32 %e.5.0, 1
br i1 false, label %bb1, label %bb7
bb7: ; preds = %bb6
ret void
}
; Show that we can turn signed comparison to unsigned and use zext while
; comparing non-negative values.
define void @test_12(i32* %p) {
; CHECK-LABEL: @test_12(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], !range !0
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV_NEXT]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%n = load i32, i32* %p, !range !0
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add i64 %iv, 1
%narrow.iv = trunc i64 %iv.next to i32
%cmp = icmp slt i32 %narrow.iv, %n
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_13a(i32 %n) {
;
; CHECK-LABEL: @test_13a(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add nsw nuw i64 %iv, 2
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ne i32 1024, %narrow.iv
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_13b(i32 %n) {
;
; CHECK-LABEL: @test_13b(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add nsw nuw i64 %iv, 2
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp ugt i32 1024, %narrow.iv
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_13c(i32 %n) {
;
; CHECK-LABEL: @test_13c(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%iv.next = add nsw nuw i64 %iv, 2
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp sgt i32 1024, %narrow.iv
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
define void @test_13d(i32 %n) {
;
; CHECK-LABEL: @test_13d(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 1024 to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -20, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 2
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [ -20, %entry ], [ %iv.next, %loop ]
%iv.next = add nsw i64 %iv, 2
%narrow.iv = trunc i64 %iv to i32
%cmp = icmp sgt i32 1024, %narrow.iv
br i1 %cmp, label %loop, label %exit
exit:
ret void
}
!0 = !{i32 0, i32 1000}