llvm-project/llvm/test/Transforms/CorrelatedValuePropagation/sub.ll

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

602 lines
16 KiB
LLVM
Raw Normal View History

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -correlated-propagation -cvp-dont-add-nowrap-flags=false -S | FileCheck %s
define void @test0(i32 %a) {
; CHECK-LABEL: @test0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, 100
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
define void @test1(i32 %a) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ugt i32 %a, 100
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
define void @test2(i32 %a) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
[ValueLattice] Merging unknown with empty CR is unknown. Currently an unknown/undef value is marked as overdefined when merged with an empty range. An empty range can occur in unreachable/dead code. When merging the new unknown state (= no value known yet) with an empty range, there still isn't any information about the value yet and we can stay in unknown. This gives a few nice improvements on the number of instructions removed by IPSCCP: Same hash: 170 (filtered out) Remaining: 67 Metric: sccp.IPNumInstRemoved Program base patch diff test-suite...rks/FreeBench/mason/mason.test 3.00 6.00 100.0% test-suite...nchmarks/McCat/18-imp/imp.test 3.00 5.00 66.7% test-suite...C/CFP2000/179.art/179.art.test 2.00 3.00 50.0% test-suite...ijndael/security-rijndael.test 2.00 3.00 50.0% test-suite...ks/Prolangs-C/agrep/agrep.test 40.00 58.00 45.0% test-suite...ce/Applications/Burg/burg.test 26.00 37.00 42.3% test-suite...cCat/03-testtrie/testtrie.test 3.00 4.00 33.3% test-suite...Source/Benchmarks/sim/sim.test 29.00 36.00 24.1% test-suite.../Applications/spiff/spiff.test 9.00 11.00 22.2% test-suite...s/FreeBench/neural/neural.test 5.00 6.00 20.0% test-suite...pplications/treecc/treecc.test 66.00 79.00 19.7% test-suite...langs-C/football/football.test 85.00 101.00 18.8% test-suite...ce/Benchmarks/PAQ8p/paq8p.test 90.00 105.00 16.7% test-suite...oxyApps-C++/miniFE/miniFE.test 37.00 43.00 16.2% test-suite...rks/FreeBench/pifft/pifft.test 26.00 30.00 15.4% test-suite...lications/sqlite3/sqlite3.test 481.00 548.00 13.9% test-suite...marks/7zip/7zip-benchmark.test 4875.00 5522.00 13.3% test-suite.../CINT2000/176.gcc/176.gcc.test 1117.00 1197.00 7.2% test-suite...0.perlbench/400.perlbench.test 1618.00 1732.00 7.0% Reviewers: efriedma, nikic, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D78667
2020-04-25 20:39:27 +08:00
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ugt i32 %a, -1
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
define void @test3(i32 %a) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, -1
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
define void @test4(i32 %a) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 2147483647
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ugt i32 %a, 2147483647
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
define void @test5(i32 %a) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 2147483647
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sle i32 %a, 2147483647
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check for a corner case where an integer value is represented with a constant
; LVILatticeValue instead of constantrange. Check that we don't fail with an
; assertion in this case.
@b = global i32 0, align 4
define void @test6(i32 %a) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A:%.*]], ptrtoint (i32* @b to i32)
; CHECK-NEXT: ret void
;
bb:
%sub = sub i32 %a, ptrtoint (i32* @b to i32)
ret void
}
; Check that we can gather information for conditions in the form of
; and ( i s< 100, Unknown )
define void @test7(i32 %a, i1 %flag) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ugt i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp ugt i32 %a, 100
%cmp = and i1 %cmp.1, %flag
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions in the form of
; and ( i s< 100, i s> 0 )
define void @test8(i32 %a) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]]
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp slt i32 %a, 100
%cmp.2 = icmp sgt i32 %a, 0
%cmp = and i1 %cmp.1, %cmp.2
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that for conditions in the form of cond1 && cond2 we don't mistakenly
; assume that !cond1 && !cond2 holds down to false path.
define void @test8_neg(i32 %a) {
; CHECK-LABEL: @test8_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sge i32 %a, 100
%cmp.2 = icmp sle i32 %a, 0
%cmp = and i1 %cmp.1, %cmp.2
br i1 %cmp, label %exit, label %bb
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions in the form of
; and ( i s< 100, and (i s> 0, Unknown )
define void @test9(i32 %a, i1 %flag) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
; CHECK-NEXT: [[CMP_3:%.*]] = and i1 [[CMP_2]], [[FLAG:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_3]]
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp slt i32 %a, 100
%cmp.2 = icmp sgt i32 %a, 0
%cmp.3 = and i1 %cmp.2, %flag
%cmp = and i1 %cmp.1, %cmp.3
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions in the form of
; and ( i s> Unknown, ... )
define void @test10(i32 %a, i32 %b, i1 %flag) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sgt i32 %a, %b
%cmp = and i1 %cmp.1, %flag
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
@limit = external global i32
define i32 @test11(i32* %p, i32 %i) {
; CHECK-LABEL: @test11(
; CHECK-NEXT: [[LIMIT:%.*]] = load i32, i32* [[P:%.*]], !range !0
; CHECK-NEXT: [[WITHIN_1:%.*]] = icmp slt i32 [[LIMIT]], [[I:%.*]]
; CHECK-NEXT: [[I_MINUS_7:%.*]] = add i32 [[I]], -7
; CHECK-NEXT: [[WITHIN_2:%.*]] = icmp slt i32 [[LIMIT]], [[I_MINUS_7]]
; CHECK-NEXT: [[WITHIN:%.*]] = and i1 [[WITHIN_1]], [[WITHIN_2]]
; CHECK-NEXT: br i1 [[WITHIN]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[I_MINUS_6:%.*]] = sub nuw nsw i32 [[I]], 6
; CHECK-NEXT: ret i32 [[I_MINUS_6]]
; CHECK: else:
; CHECK-NEXT: ret i32 0
;
%limit = load i32, i32* %p, !range !{i32 0, i32 2147483647}
%within.1 = icmp slt i32 %limit, %i
%i.minus.7 = add i32 %i, -7
%within.2 = icmp slt i32 %limit, %i.minus.7
%within = and i1 %within.1, %within.2
br i1 %within, label %then, label %else
then:
%i.minus.6 = sub i32 %i, 6
ret i32 %i.minus.6
else:
ret i32 0
}
; Check that we can gather information for conditions is the form of
; or ( i s<= -100, Unknown )
define void @test12(i32 %a, i1 %flag) {
; CHECK-LABEL: @test12(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sle i32 [[A:%.*]], -100
; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sle i32 %a, -100
%cmp = or i1 %cmp.1, %flag
br i1 %cmp, label %exit, label %bb
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions is the form of
; or ( i s>= 100, i s<= 0 )
define void @test13(i32 %a) {
; CHECK-LABEL: @test13(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sge i32 %a, 100
%cmp.2 = icmp sle i32 %a, 0
%cmp = or i1 %cmp.1, %cmp.2
br i1 %cmp, label %exit, label %bb
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that for conditions is the form of cond1 || cond2 we don't mistakenly
; assume that cond1 || cond2 holds down to true path.
define void @test13_neg(i32 %a) {
; CHECK-LABEL: @test13_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]]
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp slt i32 %a, 100
%cmp.2 = icmp sgt i32 %a, 0
%cmp = or i1 %cmp.1, %cmp.2
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions is the form of
; or ( i s>=100, or (i s<= 0, Unknown )
define void @test14(i32 %a, i1 %flag) {
; CHECK-LABEL: @test14(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A:%.*]], 100
; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
; CHECK-NEXT: [[CMP_3:%.*]] = or i1 [[CMP_2]], [[FLAG:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_3]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sge i32 %a, 100
%cmp.2 = icmp sle i32 %a, 0
%cmp.3 = or i1 %cmp.2, %flag
%cmp = or i1 %cmp.1, %cmp.3
br i1 %cmp, label %exit, label %bb
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; Check that we can gather information for conditions is the form of
; or ( i s<= Unknown, ... )
define void @test15(i32 %a, i32 %b, i1 %flag) {
; CHECK-LABEL: @test15(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP_1:%.*]] = icmp sle i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[A]], 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp.1 = icmp sle i32 %a, %b
%cmp = or i1 %cmp.1, %flag
br i1 %cmp, label %exit, label %bb
bb:
%sub = sub i32 %a, 1
br label %exit
exit:
ret void
}
; single basic block loop
; because the loop exit condition is SLT, we can supplement the iv sub
; (iv.next def) with an nsw.
define i32 @test16(i32* %n, i32* %a) {
; CHECK-LABEL: @test16(
; CHECK-NEXT: preheader:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ACC_CURR:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[X:%.*]] = load atomic i32, i32* [[A:%.*]] unordered, align 8
; CHECK-NEXT: fence acquire
; CHECK-NEXT: [[ACC_CURR]] = sub i32 [[ACC]], [[X]]
; CHECK-NEXT: [[IV_NEXT]] = sub nsw i32 [[IV]], -1
; CHECK-NEXT: [[NVAL:%.*]] = load atomic i32, i32* [[N:%.*]] unordered, align 8
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_NEXT]], [[NVAL]]
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret i32 [[ACC_CURR]]
;
preheader:
br label %loop
loop:
%iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ]
%acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ]
%x = load atomic i32, i32* %a unordered, align 8
fence acquire
%acc.curr = sub i32 %acc, %x
%iv.next = sub i32 %iv, -1
%nval = load atomic i32, i32* %n unordered, align 8
%cmp = icmp slt i32 %iv.next, %nval
br i1 %cmp, label %loop, label %exit
exit:
ret i32 %acc.curr
}
define void @test17(i32 %a) {
; CHECK-LABEL: @test17(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 1, [[A]]
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, 100
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 1, %a
br label %exit
exit:
ret void
}
define void @test18(i32 %a) {
; CHECK-LABEL: @test18(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 10000
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 -2, [[A]]
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp sgt i32 %a, 10000
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 -2, %a
br label %exit
exit:
ret void
}
define void @test19(i32 %a) {
; CHECK-LABEL: @test19(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 -1, [[A]]
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ult i32 %a, 100
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 -1, %a
br label %exit
exit:
ret void
}
define void @test20(i32 %a) {
; CHECK-LABEL: @test20(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 2147483647
; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[A]]
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ugt i32 %a, 2147483647
br i1 %cmp, label %bb, label %exit
bb:
%sub = sub i32 0, %a
br label %exit
exit:
ret void
}