You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1,25 +0,0 @@
|
||||
; RUN: opt -S < %s -correlated-propagation | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test(
|
||||
define i16 @test(i32 %a, i1 %b) {
|
||||
entry:
|
||||
%c = icmp eq i32 %a, 0
|
||||
br i1 %c, label %left, label %right
|
||||
|
||||
right:
|
||||
%d = trunc i32 %a to i1
|
||||
br label %merge
|
||||
|
||||
left:
|
||||
br i1 %b, label %merge, label %other
|
||||
|
||||
other:
|
||||
ret i16 23
|
||||
|
||||
merge:
|
||||
%f = phi i1 [%b, %left], [%d, %right]
|
||||
; CHECK: select i1 %f, i16 1, i16 0
|
||||
%h = select i1 %f, i16 1, i16 0
|
||||
; CHECK: ret i16 %h
|
||||
ret i16 %h
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -correlated-propagation
|
||||
|
||||
%struct.S2 = type {}
|
||||
|
||||
@g_128 = external global %struct.S2, align 1
|
||||
@g_106 = external global i16, align 2
|
||||
|
||||
define void @int328(i16 signext %p_82) noreturn nounwind ssp {
|
||||
entry:
|
||||
%tobool3 = icmp eq i16 %p_82, 0
|
||||
br label %for.cond.outer
|
||||
|
||||
for.cond.outer: ; preds = %for.cond.loopexit, %entry
|
||||
br label %for.cond
|
||||
|
||||
for.cond.loopexit: ; preds = %bb.nph, %for.cond9.preheader
|
||||
br label %for.cond.outer
|
||||
|
||||
for.cond.loopexit4.us-lcssa: ; preds = %if.then
|
||||
br label %for.cond.loopexit4
|
||||
|
||||
for.cond.loopexit4: ; preds = %for.cond.loopexit4.us-lcssa.us, %for.cond.loopexit4.us-lcssa
|
||||
br label %for.cond.backedge
|
||||
|
||||
for.cond: ; preds = %for.cond.backedge, %for.cond.outer
|
||||
br i1 %tobool3, label %for.cond.split.us, label %for.cond.for.cond.split_crit_edge
|
||||
|
||||
for.cond.for.cond.split_crit_edge: ; preds = %for.cond
|
||||
br label %lbl_133
|
||||
|
||||
for.cond.split.us: ; preds = %for.cond
|
||||
br label %lbl_133.us
|
||||
|
||||
lbl_133.us: ; preds = %lbl_134.us, %for.cond.split.us
|
||||
br i1 undef, label %if.else14.us-lcssa.us, label %if.then.us
|
||||
|
||||
lbl_134.us: ; preds = %if.then.us
|
||||
br i1 icmp eq (i16 ptrtoint (%struct.S2* @g_128 to i16), i16 0), label %for.cond9.preheader.us-lcssa.us, label %lbl_133.us
|
||||
|
||||
if.then.us: ; preds = %lbl_133.us
|
||||
br i1 true, label %for.cond.loopexit4.us-lcssa.us, label %lbl_134.us
|
||||
|
||||
if.else14.us-lcssa.us: ; preds = %lbl_133.us
|
||||
br label %if.else14
|
||||
|
||||
for.cond9.preheader.us-lcssa.us: ; preds = %lbl_134.us
|
||||
br label %for.cond9.preheader
|
||||
|
||||
for.cond.loopexit4.us-lcssa.us: ; preds = %if.then.us
|
||||
br label %for.cond.loopexit4
|
||||
|
||||
lbl_133: ; preds = %lbl_134, %for.cond.for.cond.split_crit_edge
|
||||
%l_109.0 = phi i16 [ 0, %for.cond.for.cond.split_crit_edge ], [ ptrtoint (%struct.S2* @g_128 to i16), %lbl_134 ]
|
||||
%tobool = icmp eq i32 undef, 0
|
||||
br i1 %tobool, label %if.else14.us-lcssa, label %if.then
|
||||
|
||||
if.then: ; preds = %lbl_133
|
||||
br i1 false, label %for.cond.loopexit4.us-lcssa, label %lbl_134
|
||||
|
||||
lbl_134: ; preds = %if.then
|
||||
br i1 icmp eq (i16 ptrtoint (%struct.S2* @g_128 to i16), i16 0), label %for.cond9.preheader.us-lcssa, label %lbl_133
|
||||
|
||||
for.cond9.preheader.us-lcssa: ; preds = %lbl_134
|
||||
br label %for.cond9.preheader
|
||||
|
||||
for.cond9.preheader: ; preds = %for.cond9.preheader.us-lcssa, %for.cond9.preheader.us-lcssa.us
|
||||
br i1 undef, label %bb.nph, label %for.cond.loopexit
|
||||
|
||||
bb.nph: ; preds = %for.cond9.preheader
|
||||
br label %for.cond.loopexit
|
||||
|
||||
if.else14.us-lcssa: ; preds = %lbl_133
|
||||
br label %if.else14
|
||||
|
||||
if.else14: ; preds = %if.else14.us-lcssa, %if.else14.us-lcssa.us
|
||||
%l_109.0.lcssa = phi i16 [ %l_109.0, %if.else14.us-lcssa ], [ 0, %if.else14.us-lcssa.us ]
|
||||
store i16 undef, i16* @g_106, align 2
|
||||
br label %for.cond.backedge
|
||||
|
||||
for.cond.backedge: ; preds = %if.else14, %for.cond.loopexit4
|
||||
br label %for.cond
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -cvp-dont-process-adds=false -S | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test0(
|
||||
define void @test0(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, 100
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test1(
|
||||
define void @test1(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, 100
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nuw nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test2(
|
||||
define void @test2(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, -1
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nuw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test3(
|
||||
define void @test3(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp ule i32 %a, -1
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test4(
|
||||
define void @test4(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, 2147483647
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test5(
|
||||
define void @test5(i32 %a) {
|
||||
entry:
|
||||
%cmp = icmp sle i32 %a, 2147483647
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add i32 %a, 1
|
||||
%add = add 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) {
|
||||
bb:
|
||||
%add = add i32 %a, ptrtoint (i32* @b to i32)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that we can gather information for conditions is the form of
|
||||
; and ( i s< 100, Unknown )
|
||||
; CHECK-LABEL: @test7(
|
||||
define void @test7(i32 %a, i1 %flag) {
|
||||
entry:
|
||||
%cmp.1 = icmp slt i32 %a, 100
|
||||
%cmp = and i1 %cmp.1, %flag
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that we can gather information for conditions is the form of
|
||||
; and ( i s< 100, i s> 0 )
|
||||
; CHECK-LABEL: @test8(
|
||||
define void @test8(i32 %a) {
|
||||
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:
|
||||
; CHECK: %add = add nuw nsw i32 %a, 1
|
||||
%add = add 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 false path.
|
||||
; CHECK-LABEL: @test8_neg(
|
||||
define void @test8_neg(i32 %a) {
|
||||
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:
|
||||
; CHECK: %add = add i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that we can gather information for conditions is the form of
|
||||
; and ( i s< 100, and (i s> 0, Unknown )
|
||||
; CHECK-LABEL: @test9(
|
||||
define void @test9(i32 %a, i1 %flag) {
|
||||
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:
|
||||
; CHECK: %add = add nuw nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that we can gather information for conditions is the form of
|
||||
; and ( i s< Unknown, ... )
|
||||
; CHECK-LABEL: @test10(
|
||||
define void @test10(i32 %a, i32 %b, i1 %flag) {
|
||||
entry:
|
||||
%cmp.1 = icmp slt i32 %a, %b
|
||||
%cmp = and i1 %cmp.1, %flag
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add i32 %a, 1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
@limit = external global i32
|
||||
; CHECK-LABEL: @test11(
|
||||
define i32 @test11(i32* %p, i32 %i) {
|
||||
%limit = load i32, i32* %p, !range !{i32 0, i32 2147483647}
|
||||
%within.1 = icmp ugt i32 %limit, %i
|
||||
%i.plus.7 = add i32 %i, 7
|
||||
%within.2 = icmp ugt i32 %limit, %i.plus.7
|
||||
%within = and i1 %within.1, %within.2
|
||||
br i1 %within, label %then, label %else
|
||||
|
||||
then:
|
||||
; CHECK: %i.plus.6 = add nuw nsw i32 %i, 6
|
||||
%i.plus.6 = add i32 %i, 6
|
||||
ret i32 %i.plus.6
|
||||
|
||||
else:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; Check that we can gather information for conditions is the form of
|
||||
; or ( i s>= 100, Unknown )
|
||||
; CHECK-LABEL: @test12(
|
||||
define void @test12(i32 %a, i1 %flag) {
|
||||
entry:
|
||||
%cmp.1 = icmp sge i32 %a, 100
|
||||
%cmp = or i1 %cmp.1, %flag
|
||||
br i1 %cmp, label %exit, label %bb
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add 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 )
|
||||
; CHECK-LABEL: @test13(
|
||||
define void @test13(i32 %a) {
|
||||
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:
|
||||
; CHECK: %add = add nuw nsw i32 %a, 1
|
||||
%add = add 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.
|
||||
; CHECK-LABEL: @test13_neg(
|
||||
define void @test13_neg(i32 %a) {
|
||||
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:
|
||||
; CHECK: %add = add i32 %a, 1
|
||||
%add = add 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 )
|
||||
; CHECK-LABEL: @test14(
|
||||
define void @test14(i32 %a, i1 %flag) {
|
||||
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:
|
||||
; CHECK: %add = add nuw nsw i32 %a, 1
|
||||
%add = add 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, ... )
|
||||
; CHECK-LABEL: @test15(
|
||||
define void @test15(i32 %a, i32 %b, i1 %flag) {
|
||||
entry:
|
||||
%cmp.1 = icmp sge i32 %a, %b
|
||||
%cmp = or i1 %cmp.1, %flag
|
||||
br i1 %cmp, label %exit, label %bb
|
||||
|
||||
bb:
|
||||
; CHECK: %add = add nsw i32 %a, 1
|
||||
%add = add 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 add
|
||||
; (iv.next def) with an nsw.
|
||||
; CHECK-LABEL: @test16(
|
||||
define i32 @test16(i32* %n, i32* %a) {
|
||||
preheader:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
; CHECK: %iv.next = add nsw i32 %iv, 1
|
||||
%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 = add i32 %acc, %x
|
||||
%iv.next = add 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
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
; RUN: opt -S -correlated-propagation -debug-only=lazy-value-info <%s 2>&1 | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
;
|
||||
; Shortcut in Correlated Value Propagation ensures not to take Lazy Value Info
|
||||
; analysis for %a.i and %tmp because %a.i is defined by alloca and %tmp is
|
||||
; defined by alloca + bitcast. We know the ret value of alloca is nonnull.
|
||||
;
|
||||
; CHECK-NOT: LVI Getting edge value %a.i = alloca i64, align 8 at 'for.body'
|
||||
; CHECK-NOT: LVI Getting edge value %tmp = bitcast i64* %a.i to i8* from 'for.cond' to 'for.body'
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@.str = private unnamed_addr constant [8 x i8] c"a = %l\0A\00", align 1
|
||||
|
||||
; Function Attrs: argmemonly nounwind
|
||||
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
|
||||
|
||||
declare void @hoo(i64*)
|
||||
|
||||
declare i32 @printf(i8* nocapture readonly, ...)
|
||||
|
||||
; Function Attrs: argmemonly nounwind
|
||||
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
|
||||
|
||||
define void @goo(i32 %N, i64* %b) {
|
||||
entry:
|
||||
%a.i = alloca i64, align 8
|
||||
%tmp = bitcast i64* %a.i to i8*
|
||||
%c = getelementptr inbounds i64, i64* %b, i64 0
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.body, %entry
|
||||
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
||||
%cmp = icmp slt i32 %i.0, %N
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp)
|
||||
call void @hoo(i64* %a.i)
|
||||
call void @hoo(i64* %c)
|
||||
%tmp1 = load volatile i64, i64* %a.i, align 8
|
||||
%call.i = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %tmp1)
|
||||
call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp)
|
||||
%inc = add nsw i32 %i.0, 1
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
define void @test1(i32 %n) {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.body, %entry
|
||||
%a = phi i32 [ %n, %entry ], [ %shr, %for.body ]
|
||||
%cmp = icmp sgt i32 %a, 1
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
; CHECK: lshr i32 %a, 5
|
||||
%shr = ashr i32 %a, 5
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
;; Negative test to show transform doesn't happen unless n > 0.
|
||||
; CHECK-LABEL: @test2
|
||||
define void @test2(i32 %n) {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.body, %entry
|
||||
%a = phi i32 [ %n, %entry ], [ %shr, %for.body ]
|
||||
%cmp = icmp sgt i32 %a, -2
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
; CHECK: ashr i32 %a, 2
|
||||
%shr = ashr i32 %a, 2
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
;; Non looping test case.
|
||||
; CHECK-LABEL: @test3
|
||||
define void @test3(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: lshr exact i32 %n, 4
|
||||
%shr = ashr exact i32 %n, 4
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; looping case where loop has exactly one block
|
||||
; at the point of ashr, we know that the operand is always greater than 0,
|
||||
; because of the guard before it, so we can transform it to lshr.
|
||||
declare void @llvm.experimental.guard(i1,...)
|
||||
; CHECK-LABEL: @test4
|
||||
define void @test4(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
loop:
|
||||
; CHECK: lshr i32 %a, 1
|
||||
%a = phi i32 [ %n, %entry ], [ %shr, %loop ]
|
||||
%cond = icmp sgt i32 %a, 2
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
|
||||
%shr = ashr i32 %a, 1
|
||||
br i1 %cond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; same test as above with assume instead of guard.
|
||||
declare void @llvm.assume(i1)
|
||||
; CHECK-LABEL: @test5
|
||||
define void @test5(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
loop:
|
||||
; CHECK: lshr i32 %a, 1
|
||||
%a = phi i32 [ %n, %entry ], [ %shr, %loop ]
|
||||
%cond = icmp sgt i32 %a, 4
|
||||
call void @llvm.assume(i1 %cond)
|
||||
%shr = ashr i32 %a, 1
|
||||
%loopcond = icmp sgt i32 %shr, 8
|
||||
br i1 %loopcond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
@ -1,487 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
; PR2581
|
||||
|
||||
; CHECK-LABEL: @test1(
|
||||
define i32 @test1(i1 %C) nounwind {
|
||||
br i1 %C, label %exit, label %body
|
||||
|
||||
body: ; preds = %0
|
||||
; CHECK-NOT: select
|
||||
%A = select i1 %C, i32 10, i32 11 ; <i32> [#uses=1]
|
||||
; CHECK: ret i32 11
|
||||
ret i32 %A
|
||||
|
||||
exit: ; preds = %0
|
||||
; CHECK: ret i32 10
|
||||
ret i32 10
|
||||
}
|
||||
|
||||
; PR4420
|
||||
declare i1 @ext()
|
||||
; CHECK-LABEL: @test2(
|
||||
define i1 @test2() {
|
||||
entry:
|
||||
%cond = tail call i1 @ext() ; <i1> [#uses=2]
|
||||
br i1 %cond, label %bb1, label %bb2
|
||||
|
||||
bb1: ; preds = %entry
|
||||
%cond2 = tail call i1 @ext() ; <i1> [#uses=1]
|
||||
br i1 %cond2, label %bb3, label %bb2
|
||||
|
||||
bb2: ; preds = %bb1, %entry
|
||||
; CHECK-NOT: phi i1
|
||||
%cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ] ; <i1> [#uses=1]
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %cond_merge
|
||||
|
||||
bb3: ; preds = %bb1
|
||||
%res = tail call i1 @ext() ; <i1> [#uses=1]
|
||||
; CHECK: ret i1 %res
|
||||
ret i1 %res
|
||||
}
|
||||
|
||||
; PR4855
|
||||
@gv = internal constant i8 7
|
||||
; CHECK-LABEL: @test3(
|
||||
define i8 @test3(i8* %a) nounwind {
|
||||
entry:
|
||||
%cond = icmp eq i8* %a, @gv
|
||||
br i1 %cond, label %bb2, label %bb
|
||||
|
||||
bb: ; preds = %entry
|
||||
ret i8 0
|
||||
|
||||
bb2: ; preds = %entry
|
||||
; CHECK: %should_be_const = load i8, i8* @gv
|
||||
%should_be_const = load i8, i8* %a
|
||||
ret i8 %should_be_const
|
||||
}
|
||||
|
||||
; PR1757
|
||||
; CHECK-LABEL: @test4(
|
||||
define i32 @test4(i32) {
|
||||
EntryBlock:
|
||||
; CHECK: icmp sgt i32 %0, 2
|
||||
%.demorgan = icmp sgt i32 %0, 2
|
||||
br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
|
||||
|
||||
GreaterThanTwo:
|
||||
; CHECK-NOT: icmp eq i32 %0, 2
|
||||
icmp eq i32 %0, 2
|
||||
; CHECK: br i1 false
|
||||
br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
|
||||
|
||||
NotTwoAndGreaterThanTwo:
|
||||
ret i32 2
|
||||
|
||||
Impossible:
|
||||
ret i32 1
|
||||
|
||||
LessThanOrEqualToTwo:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32* @f(i32*)
|
||||
define void @test5(i32* %x, i32* %y) {
|
||||
; CHECK-LABEL: @test5(
|
||||
entry:
|
||||
%pre = icmp eq i32* %x, null
|
||||
br i1 %pre, label %return, label %loop
|
||||
|
||||
loop:
|
||||
%phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
|
||||
; CHECK: %phi = phi i32* [ %f, %loop ], [ %x, %entry ]
|
||||
%f = tail call i32* @f(i32* %phi)
|
||||
%cmp1 = icmp ne i32* %f, %y
|
||||
%sel = select i1 %cmp1, i32* %f, i32* null
|
||||
%cmp2 = icmp eq i32* %sel, null
|
||||
br i1 %cmp2, label %return, label %loop
|
||||
|
||||
return:
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @switch1(i32 %s) {
|
||||
; CHECK-LABEL: @switch1(
|
||||
entry:
|
||||
%cmp = icmp slt i32 %s, 0
|
||||
br i1 %cmp, label %negative, label %out
|
||||
|
||||
negative:
|
||||
switch i32 %s, label %out [
|
||||
; CHECK: switch i32 %s, label %out
|
||||
i32 0, label %out
|
||||
; CHECK-NOT: i32 0
|
||||
i32 1, label %out
|
||||
; CHECK-NOT: i32 1
|
||||
i32 -1, label %next
|
||||
; CHECK-DAG: i32 -1, label %next
|
||||
i32 -2, label %next
|
||||
; CHECK-DAG: i32 -2, label %next
|
||||
i32 2, label %out
|
||||
; CHECK-NOT: i32 2
|
||||
i32 3, label %out
|
||||
; CHECK-NOT: i32 3
|
||||
]
|
||||
|
||||
out:
|
||||
%p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
|
||||
ret i32 %p
|
||||
|
||||
next:
|
||||
%q = phi i32 [ 0, %negative ], [ 0, %negative ]
|
||||
ret i32 %q
|
||||
}
|
||||
|
||||
define i32 @switch2(i32 %s) {
|
||||
; CHECK-LABEL: @switch2(
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %s, 0
|
||||
br i1 %cmp, label %positive, label %out
|
||||
|
||||
positive:
|
||||
switch i32 %s, label %out [
|
||||
i32 0, label %out
|
||||
i32 -1, label %next
|
||||
i32 -2, label %next
|
||||
]
|
||||
; CHECK: br label %out
|
||||
|
||||
out:
|
||||
%p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
|
||||
ret i32 %p
|
||||
|
||||
next:
|
||||
%q = phi i32 [ 0, %positive ], [ 0, %positive ]
|
||||
ret i32 %q
|
||||
}
|
||||
|
||||
define i32 @switch3(i32 %s) {
|
||||
; CHECK-LABEL: @switch3(
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %s, 0
|
||||
br i1 %cmp, label %positive, label %out
|
||||
|
||||
positive:
|
||||
switch i32 %s, label %out [
|
||||
i32 -1, label %out
|
||||
i32 -2, label %next
|
||||
i32 -3, label %next
|
||||
]
|
||||
; CHECK: br label %out
|
||||
|
||||
out:
|
||||
%p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
|
||||
ret i32 %p
|
||||
|
||||
next:
|
||||
%q = phi i32 [ 0, %positive ], [ 0, %positive ]
|
||||
ret i32 %q
|
||||
}
|
||||
|
||||
define void @switch4(i32 %s) {
|
||||
; CHECK-LABEL: @switch4(
|
||||
entry:
|
||||
%cmp = icmp eq i32 %s, 0
|
||||
br i1 %cmp, label %zero, label %out
|
||||
|
||||
zero:
|
||||
switch i32 %s, label %out [
|
||||
i32 0, label %next
|
||||
i32 1, label %out
|
||||
i32 -1, label %out
|
||||
]
|
||||
; CHECK: br label %next
|
||||
|
||||
out:
|
||||
ret void
|
||||
|
||||
next:
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @arg_attribute(i8* nonnull %a) {
|
||||
; CHECK-LABEL: @arg_attribute(
|
||||
; CHECK: ret i1 false
|
||||
%cmp = icmp eq i8* %a, null
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
declare nonnull i8* @return_nonnull()
|
||||
define i1 @call_attribute() {
|
||||
; CHECK-LABEL: @call_attribute(
|
||||
; CHECK: ret i1 false
|
||||
%a = call i8* @return_nonnull()
|
||||
%cmp = icmp eq i8* %a, null
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @umin(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @umin(
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%cmp2 = icmp ult i32 %b, 20
|
||||
br i1 %cmp2, label %b_guard, label %out
|
||||
|
||||
b_guard:
|
||||
%sel_cmp = icmp ult i32 %a, %b
|
||||
%min = select i1 %sel_cmp, i32 %a, i32 %b
|
||||
%res = icmp eq i32 %min, 7
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @smin(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @smin(
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%cmp2 = icmp ult i32 %b, 20
|
||||
br i1 %cmp2, label %b_guard, label %out
|
||||
|
||||
b_guard:
|
||||
%sel_cmp = icmp sle i32 %a, %b
|
||||
%min = select i1 %sel_cmp, i32 %a, i32 %b
|
||||
%res = icmp eq i32 %min, 7
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @smax(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @smax(
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%cmp2 = icmp sgt i32 %b, 20
|
||||
br i1 %cmp2, label %b_guard, label %out
|
||||
|
||||
b_guard:
|
||||
%sel_cmp = icmp sge i32 %a, %b
|
||||
%max = select i1 %sel_cmp, i32 %a, i32 %b
|
||||
%res = icmp eq i32 %max, 7
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @umax(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @umax(
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%cmp2 = icmp sgt i32 %b, 20
|
||||
br i1 %cmp2, label %b_guard, label %out
|
||||
|
||||
b_guard:
|
||||
%sel_cmp = icmp uge i32 %a, %b
|
||||
%max = select i1 %sel_cmp, i32 %a, i32 %b
|
||||
%res = icmp eq i32 %max, 7
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @clamp_low1(i32 %a) {
|
||||
; CHECK-LABEL: @clamp_low1(
|
||||
entry:
|
||||
%cmp = icmp sge i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%sel_cmp = icmp eq i32 %a, 5
|
||||
%add = add i32 %a, -1
|
||||
%sel = select i1 %sel_cmp, i32 5, i32 %a
|
||||
%res = icmp eq i32 %sel, 4
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @clamp_low2(i32 %a) {
|
||||
; CHECK-LABEL: @clamp_low2(
|
||||
entry:
|
||||
%cmp = icmp sge i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%sel_cmp = icmp ne i32 %a, 5
|
||||
%add = add i32 %a, -1
|
||||
%sel = select i1 %sel_cmp, i32 %a, i32 5
|
||||
%res = icmp eq i32 %sel, 4
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @clamp_high1(i32 %a) {
|
||||
; CHECK-LABEL: @clamp_high1(
|
||||
entry:
|
||||
%cmp = icmp sle i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%sel_cmp = icmp eq i32 %a, 5
|
||||
%add = add i32 %a, 1
|
||||
%sel = select i1 %sel_cmp, i32 5, i32 %a
|
||||
%res = icmp eq i32 %sel, 6
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @clamp_high2(i32 %a) {
|
||||
; CHECK-LABEL: @clamp_high2(
|
||||
entry:
|
||||
%cmp = icmp sle i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%sel_cmp = icmp ne i32 %a, 5
|
||||
%add = add i32 %a, 1
|
||||
%sel = select i1 %sel_cmp, i32 %a, i32 5
|
||||
%res = icmp eq i32 %sel, 6
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
; Just showing arbitrary constants work, not really a clamp
|
||||
define i1 @clamp_high3(i32 %a) {
|
||||
; CHECK-LABEL: @clamp_high3(
|
||||
entry:
|
||||
%cmp = icmp sle i32 %a, 5
|
||||
br i1 %cmp, label %a_guard, label %out
|
||||
|
||||
a_guard:
|
||||
%sel_cmp = icmp ne i32 %a, 5
|
||||
%add = add i32 %a, 100
|
||||
%sel = select i1 %sel_cmp, i32 %a, i32 5
|
||||
%res = icmp eq i32 %sel, 105
|
||||
br label %next
|
||||
next:
|
||||
; CHECK: next:
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %res
|
||||
out:
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
define i1 @zext_unknown(i8 %a) {
|
||||
; CHECK-LABEL: @zext_unknown
|
||||
; CHECK: ret i1 true
|
||||
entry:
|
||||
%a32 = zext i8 %a to i32
|
||||
%cmp = icmp sle i32 %a32, 256
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @trunc_unknown(i32 %a) {
|
||||
; CHECK-LABEL: @trunc_unknown
|
||||
; CHECK: ret i1 true
|
||||
entry:
|
||||
%a8 = trunc i32 %a to i8
|
||||
%a32 = sext i8 %a8 to i32
|
||||
%cmp = icmp sle i32 %a32, 128
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; TODO: missed optimization
|
||||
; Make sure we exercise non-integer inputs to unary operators (i.e. crash
|
||||
; check).
|
||||
define i1 @bitcast_unknown(float %a) {
|
||||
; CHECK-LABEL: @bitcast_unknown
|
||||
; CHECK: ret i1 %cmp
|
||||
entry:
|
||||
%a32 = bitcast float %a to i32
|
||||
%cmp = icmp sle i32 %a32, 128
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @bitcast_unknown2(i8* %p) {
|
||||
; CHECK-LABEL: @bitcast_unknown2
|
||||
; CHECK: ret i1 %cmp
|
||||
entry:
|
||||
%p64 = ptrtoint i8* %p to i64
|
||||
%cmp = icmp sle i64 %p64, 128
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
|
||||
define i1 @and_unknown(i32 %a) {
|
||||
; CHECK-LABEL: @and_unknown
|
||||
; CHECK: ret i1 true
|
||||
entry:
|
||||
%and = and i32 %a, 128
|
||||
%cmp = icmp sle i32 %and, 128
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @lshr_unknown(i32 %a) {
|
||||
; CHECK-LABEL: @lshr_unknown
|
||||
; CHECK: ret i1 true
|
||||
entry:
|
||||
%and = lshr i32 %a, 30
|
||||
%cmp = icmp sle i32 %and, 128
|
||||
br label %exit
|
||||
exit:
|
||||
ret i1 %cmp
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
; RUN: opt -correlated-propagation -S < %s | FileCheck %s
|
||||
; Checks that we don't crash on conflicting facts about a value
|
||||
; (i.e. unreachable code)
|
||||
|
||||
; Test that we can handle conflict edge facts
|
||||
define i8 @test(i8 %a) {
|
||||
; CHECK-LABEL: @test
|
||||
%cmp1 = icmp eq i8 %a, 5
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
next:
|
||||
%cmp2 = icmp eq i8 %a, 3
|
||||
; CHECK: br i1 false, label %dead, label %exit
|
||||
br i1 %cmp2, label %dead, label %exit
|
||||
dead:
|
||||
; CHECK-LABEL: dead:
|
||||
; CHECK: ret i8 5
|
||||
; NOTE: undef, or 3 would be equal valid
|
||||
ret i8 %a
|
||||
exit:
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
; Test that we can handle conflicting assume vs edge facts
|
||||
define i8 @test2(i8 %a) {
|
||||
; CHECK-LABEL: @test2
|
||||
%cmp1 = icmp eq i8 %a, 5
|
||||
call void @llvm.assume(i1 %cmp1)
|
||||
%cmp2 = icmp eq i8 %a, 3
|
||||
; CHECK: br i1 false, label %dead, label %exit
|
||||
br i1 %cmp2, label %dead, label %exit
|
||||
dead:
|
||||
ret i8 %a
|
||||
exit:
|
||||
ret i8 0
|
||||
}
|
||||
|
||||
define i8 @test3(i8 %a) {
|
||||
; CHECK-LABEL: @test3
|
||||
%cmp1 = icmp eq i8 %a, 5
|
||||
br i1 %cmp1, label %dead, label %exit
|
||||
dead:
|
||||
%cmp2 = icmp eq i8 %a, 3
|
||||
; CHECK: call void @llvm.assume(i1 false)
|
||||
call void @llvm.assume(i1 %cmp2)
|
||||
ret i8 %a
|
||||
exit:
|
||||
ret i8 0
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation
|
||||
|
||||
; PR8161
|
||||
define void @test1() nounwind ssp {
|
||||
entry:
|
||||
br label %for.end
|
||||
|
||||
for.cond.us.us: ; preds = %for.cond.us.us
|
||||
%cmp6.i.us.us = icmp sgt i32 1, 0
|
||||
%lor.ext.i.us.us = zext i1 %cmp6.i.us.us to i32
|
||||
%lor.ext.add.i.us.us = select i1 %cmp6.i.us.us, i32 %lor.ext.i.us.us, i32 undef
|
||||
%conv.i.us.us = trunc i32 %lor.ext.add.i.us.us to i16
|
||||
%sext.us.us = shl i16 %conv.i.us.us, 8
|
||||
%conv6.us.us = ashr i16 %sext.us.us, 8
|
||||
%and.us.us = and i16 %conv6.us.us, %and.us.us
|
||||
br i1 false, label %for.end, label %for.cond.us.us
|
||||
|
||||
for.end: ; preds = %for.cond.us, %for.cond.us.us, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
; PR 8790
|
||||
define void @test2() nounwind ssp {
|
||||
entry:
|
||||
br label %func_29.exit
|
||||
|
||||
sdf.exit.i:
|
||||
%l_44.1.mux.i = select i1 %tobool5.not.i, i8 %l_44.1.mux.i, i8 1
|
||||
br label %srf.exit.i
|
||||
|
||||
srf.exit.i:
|
||||
%tobool5.not.i = icmp ne i8 undef, 0
|
||||
br i1 %tobool5.not.i, label %sdf.exit.i, label %func_29.exit
|
||||
|
||||
func_29.exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; PR13972
|
||||
define void @test3() nounwind {
|
||||
for.body:
|
||||
br label %return
|
||||
|
||||
for.cond.i: ; preds = %if.else.i, %for.body.i
|
||||
%e.2.i = phi i32 [ %e.2.i, %if.else.i ], [ -8, %for.body.i ]
|
||||
br i1 undef, label %return, label %for.body.i
|
||||
|
||||
for.body.i: ; preds = %for.cond.i
|
||||
switch i32 %e.2.i, label %for.cond3.i [
|
||||
i32 -3, label %if.else.i
|
||||
i32 0, label %for.cond.i
|
||||
]
|
||||
|
||||
for.cond3.i: ; preds = %for.cond3.i, %for.body.i
|
||||
br label %for.cond3.i
|
||||
|
||||
if.else.i: ; preds = %for.body.i
|
||||
br label %for.cond.i
|
||||
|
||||
return: ; preds = %for.cond.i, %for.body
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @test4(i32 %int) {
|
||||
%a0 = icmp ult i32 %int, 100
|
||||
%a1 = and i1 %a0, %a0
|
||||
%a2 = and i1 %a1, %a1
|
||||
%a3 = and i1 %a2, %a2
|
||||
%a4 = and i1 %a3, %a3
|
||||
%a5 = and i1 %a4, %a4
|
||||
%a6 = and i1 %a5, %a5
|
||||
%a7 = and i1 %a6, %a6
|
||||
%a8 = and i1 %a7, %a7
|
||||
%a9 = and i1 %a8, %a8
|
||||
%a10 = and i1 %a9, %a9
|
||||
%a11 = and i1 %a10, %a10
|
||||
%a12 = and i1 %a11, %a11
|
||||
%a13 = and i1 %a12, %a12
|
||||
%a14 = and i1 %a13, %a13
|
||||
%a15 = and i1 %a14, %a14
|
||||
%a16 = and i1 %a15, %a15
|
||||
%a17 = and i1 %a16, %a16
|
||||
%a18 = and i1 %a17, %a17
|
||||
%a19 = and i1 %a18, %a18
|
||||
%a20 = and i1 %a19, %a19
|
||||
%a21 = and i1 %a20, %a20
|
||||
%a22 = and i1 %a21, %a21
|
||||
%a23 = and i1 %a22, %a22
|
||||
%a24 = and i1 %a23, %a23
|
||||
%a25 = and i1 %a24, %a24
|
||||
%a26 = and i1 %a25, %a25
|
||||
%a27 = and i1 %a26, %a26
|
||||
%a28 = and i1 %a27, %a27
|
||||
%a29 = and i1 %a28, %a28
|
||||
%a30 = and i1 %a29, %a29
|
||||
%a31 = and i1 %a30, %a30
|
||||
%a32 = and i1 %a31, %a31
|
||||
%a33 = and i1 %a32, %a32
|
||||
%a34 = and i1 %a33, %a33
|
||||
%a35 = and i1 %a34, %a34
|
||||
%a36 = and i1 %a35, %a35
|
||||
%a37 = and i1 %a36, %a36
|
||||
%a38 = and i1 %a37, %a37
|
||||
%a39 = and i1 %a38, %a38
|
||||
%a40 = and i1 %a39, %a39
|
||||
%a41 = and i1 %a40, %a40
|
||||
%a42 = and i1 %a41, %a41
|
||||
%a43 = and i1 %a42, %a42
|
||||
%a44 = and i1 %a43, %a43
|
||||
%a45 = and i1 %a44, %a44
|
||||
%a46 = and i1 %a45, %a45
|
||||
%a47 = and i1 %a46, %a46
|
||||
%a48 = and i1 %a47, %a47
|
||||
%a49 = and i1 %a48, %a48
|
||||
%a50 = and i1 %a49, %a49
|
||||
%a51 = and i1 %a50, %a50
|
||||
%a52 = and i1 %a51, %a51
|
||||
%a53 = and i1 %a52, %a52
|
||||
%a54 = and i1 %a53, %a53
|
||||
%a55 = and i1 %a54, %a54
|
||||
%a56 = and i1 %a55, %a55
|
||||
%a57 = and i1 %a56, %a56
|
||||
%a58 = and i1 %a57, %a57
|
||||
%a59 = and i1 %a58, %a58
|
||||
%a60 = and i1 %a59, %a59
|
||||
%a61 = and i1 %a60, %a60
|
||||
%a62 = and i1 %a61, %a61
|
||||
%a63 = and i1 %a62, %a62
|
||||
%a64 = and i1 %a63, %a63
|
||||
%a65 = and i1 %a64, %a64
|
||||
%a66 = and i1 %a65, %a65
|
||||
%a67 = and i1 %a66, %a66
|
||||
%a68 = and i1 %a67, %a67
|
||||
%a69 = and i1 %a68, %a68
|
||||
%a70 = and i1 %a69, %a69
|
||||
%a71 = and i1 %a70, %a70
|
||||
%a72 = and i1 %a71, %a71
|
||||
%a73 = and i1 %a72, %a72
|
||||
%a74 = and i1 %a73, %a73
|
||||
%a75 = and i1 %a74, %a74
|
||||
%a76 = and i1 %a75, %a75
|
||||
%a77 = and i1 %a76, %a76
|
||||
%a78 = and i1 %a77, %a77
|
||||
%a79 = and i1 %a78, %a78
|
||||
%a80 = and i1 %a79, %a79
|
||||
%a81 = and i1 %a80, %a80
|
||||
%a82 = and i1 %a81, %a81
|
||||
%a83 = and i1 %a82, %a82
|
||||
%a84 = and i1 %a83, %a83
|
||||
%a85 = and i1 %a84, %a84
|
||||
%a86 = and i1 %a85, %a85
|
||||
%a87 = and i1 %a86, %a86
|
||||
%a88 = and i1 %a87, %a87
|
||||
%a89 = and i1 %a88, %a88
|
||||
%a90 = and i1 %a89, %a89
|
||||
%a91 = and i1 %a90, %a90
|
||||
%a92 = and i1 %a91, %a91
|
||||
%a93 = and i1 %a92, %a92
|
||||
%a94 = and i1 %a93, %a93
|
||||
%a95 = and i1 %a94, %a94
|
||||
%a96 = and i1 %a95, %a95
|
||||
%a97 = and i1 %a96, %a96
|
||||
%a98 = and i1 %a97, %a97
|
||||
%a99 = and i1 %a98, %a98
|
||||
%a100 = and i1 %a99, %a99
|
||||
%a101 = and i1 %a100, %a100
|
||||
%a102 = and i1 %a101, %a101
|
||||
%a103 = and i1 %a102, %a102
|
||||
%a104 = and i1 %a103, %a103
|
||||
%a105 = and i1 %a104, %a104
|
||||
%a106 = and i1 %a105, %a105
|
||||
%a107 = and i1 %a106, %a106
|
||||
%a108 = and i1 %a107, %a107
|
||||
%a109 = and i1 %a108, %a108
|
||||
%a110 = and i1 %a109, %a109
|
||||
%a111 = and i1 %a110, %a110
|
||||
%a112 = and i1 %a111, %a111
|
||||
%a113 = and i1 %a112, %a112
|
||||
%a114 = and i1 %a113, %a113
|
||||
%a115 = and i1 %a114, %a114
|
||||
%a116 = and i1 %a115, %a115
|
||||
%a117 = and i1 %a116, %a116
|
||||
%a118 = and i1 %a117, %a117
|
||||
%a119 = and i1 %a118, %a118
|
||||
%a120 = and i1 %a119, %a119
|
||||
%a121 = and i1 %a120, %a120
|
||||
%a122 = and i1 %a121, %a121
|
||||
%a123 = and i1 %a122, %a122
|
||||
%a124 = and i1 %a123, %a123
|
||||
%a125 = and i1 %a124, %a124
|
||||
%a126 = and i1 %a125, %a125
|
||||
%a127 = and i1 %a126, %a126
|
||||
%cond = and i1 %a127, %a127
|
||||
br i1 %cond, label %then, label %else
|
||||
|
||||
then:
|
||||
%result = icmp eq i32 %int, 255
|
||||
ret i1 %result
|
||||
|
||||
else:
|
||||
ret i1 false
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
; RUN: opt -correlated-propagation -S < %s | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1,...)
|
||||
|
||||
define i1 @test1(i32 %a) {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK: %alive = icmp eq i32 %a, 8
|
||||
; CHECK-NEXT: %result = or i1 false, %alive
|
||||
%cmp = icmp ult i32 %a, 16
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
%dead = icmp eq i32 %a, 16
|
||||
%alive = icmp eq i32 %a, 8
|
||||
%result = or i1 %dead, %alive
|
||||
ret i1 %result
|
||||
}
|
||||
|
||||
define i1 @test2(i32 %a) {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK: continue:
|
||||
; CHECK-NEXT: %alive = icmp eq i32 %a, 8
|
||||
; CHECK-NEXT: %result = or i1 false, %alive
|
||||
%cmp = icmp ult i32 %a, 16
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
br label %continue
|
||||
|
||||
continue:
|
||||
%dead = icmp eq i32 %a, 16
|
||||
%alive = icmp eq i32 %a, 8
|
||||
%result = or i1 %dead, %alive
|
||||
ret i1 %result
|
||||
}
|
||||
|
||||
define i1 @test3(i32 %a, i1 %flag) {
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK: continue:
|
||||
; CHECK-NEXT: %alive.1 = icmp eq i32 %a, 16
|
||||
; CHECK-NEXT: %alive.2 = icmp eq i32 %a, 8
|
||||
; CHECK-NEXT: %result = or i1 %alive.1, %alive.2
|
||||
br i1 %flag, label %true, label %false
|
||||
|
||||
true:
|
||||
%cmp = icmp ult i32 %a, 16
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
br label %continue
|
||||
|
||||
false:
|
||||
br label %continue
|
||||
|
||||
continue:
|
||||
%alive.1 = icmp eq i32 %a, 16
|
||||
%alive.2 = icmp eq i32 %a, 8
|
||||
%result = or i1 %alive.1, %alive.2
|
||||
ret i1 %result
|
||||
}
|
||||
|
||||
define i1 @test4(i32 %a, i1 %flag) {
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK: continue:
|
||||
; CHECK-NEXT: %alive = icmp eq i32 %a, 12
|
||||
; CHECK-NEXT: %result = or i1 false, %alive
|
||||
br i1 %flag, label %true, label %false
|
||||
|
||||
true:
|
||||
%cmp.t = icmp ult i32 %a, 16
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp.t) [ "deopt"() ]
|
||||
br label %continue
|
||||
|
||||
false:
|
||||
%cmp.f = icmp ult i32 %a, 12
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp.f) [ "deopt"() ]
|
||||
br label %continue
|
||||
|
||||
continue:
|
||||
%dead = icmp eq i32 %a, 16
|
||||
%alive = icmp eq i32 %a, 12
|
||||
%result = or i1 %dead, %alive
|
||||
ret i1 %result
|
||||
}
|
||||
|
||||
define i1 @test5(i32 %a) {
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK: continue:
|
||||
; CHECK-NEXT: %alive = icmp eq i32 %a.plus.8, 16
|
||||
; CHECK-NEXT: %result = or i1 false, %alive
|
||||
%cmp = icmp ult i32 %a, 16
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
%a.plus.8 = add i32 %a, 8
|
||||
br label %continue
|
||||
|
||||
continue:
|
||||
%dead = icmp eq i32 %a.plus.8, 24
|
||||
%alive = icmp eq i32 %a.plus.8, 16
|
||||
%result = or i1 %dead, %alive
|
||||
ret i1 %result
|
||||
}
|
||||
|
||||
; Check that we handle the case when the guard is the very first instruction in
|
||||
; a basic block.
|
||||
define i1 @test6(i32 %a) {
|
||||
; CHECK-LABEL: @test6(
|
||||
; CHECK: %alive = icmp eq i32 %a, 8
|
||||
; CHECK-NEXT: %result = or i1 false, %alive
|
||||
%cmp = icmp ult i32 %a, 16
|
||||
br label %continue
|
||||
|
||||
continue:
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
%dead = icmp eq i32 %a, 16
|
||||
%alive = icmp eq i32 %a, 8
|
||||
%result = or i1 %dead, %alive
|
||||
ret i1 %result
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
; RUN: opt -correlated-propagation -S %s | FileCheck %s
|
||||
; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.10.0"
|
||||
|
||||
; Function Attrs: noreturn
|
||||
declare void @check1(i1) #1
|
||||
|
||||
; Function Attrs: noreturn
|
||||
declare void @check2(i1) #1
|
||||
|
||||
; Make sure we propagate the value of %tmp35 to the true/false cases
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: call void @check1(i1 false)
|
||||
; CHECK: call void @check2(i1 true)
|
||||
define void @test1(i64 %tmp35) {
|
||||
bb:
|
||||
%tmp36 = icmp sgt i64 %tmp35, 0
|
||||
br i1 %tmp36, label %bb_true, label %bb_false
|
||||
|
||||
bb_true:
|
||||
%tmp47 = icmp slt i64 %tmp35, 0
|
||||
tail call void @check1(i1 %tmp47) #4
|
||||
unreachable
|
||||
|
||||
bb_false:
|
||||
%tmp48 = icmp sle i64 %tmp35, 0
|
||||
tail call void @check2(i1 %tmp48) #4
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: noreturn
|
||||
; This is the same as test1 but with a diamond to ensure we
|
||||
; get %tmp36 from both true and false BBs.
|
||||
; CHECK-LABEL: @test2
|
||||
; CHECK: call void @check1(i1 false)
|
||||
; CHECK: call void @check2(i1 true)
|
||||
define void @test2(i64 %tmp35, i1 %inner_cmp) {
|
||||
bb:
|
||||
%tmp36 = icmp sgt i64 %tmp35, 0
|
||||
br i1 %tmp36, label %bb_true, label %bb_false
|
||||
|
||||
bb_true:
|
||||
br i1 %inner_cmp, label %inner_true, label %inner_false
|
||||
|
||||
inner_true:
|
||||
br label %merge
|
||||
|
||||
inner_false:
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%tmp47 = icmp slt i64 %tmp35, 0
|
||||
tail call void @check1(i1 %tmp47) #0
|
||||
unreachable
|
||||
|
||||
bb_false:
|
||||
%tmp48 = icmp sle i64 %tmp35, 0
|
||||
tail call void @check2(i1 %tmp48) #4
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #4 = { noreturn }
|
@ -1,163 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
|
||||
define void @test1(i8* %ptr) {
|
||||
; CHECK: test1
|
||||
%A = load i8, i8* %ptr
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %ptr, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test2(i8* %ptr) {
|
||||
; CHECK: test2
|
||||
store i8 0, i8* %ptr
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %ptr, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test3() {
|
||||
; CHECK: test3
|
||||
%ptr = alloca i8
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %ptr, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
|
||||
define void @test4(i8* %dest, i8* %src) {
|
||||
; CHECK: test4
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i32 1, i1 false)
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %dest, null
|
||||
icmp ne i8* %src, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
|
||||
define void @test5(i8* %dest, i8* %src) {
|
||||
; CHECK: test5
|
||||
call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i32 1, i1 false)
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %dest, null
|
||||
icmp ne i8* %src, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)
|
||||
define void @test6(i8* %dest) {
|
||||
; CHECK: test6
|
||||
call void @llvm.memset.p0i8.i32(i8* %dest, i8 255, i32 1, i32 1, i1 false)
|
||||
br label %bb
|
||||
bb:
|
||||
icmp ne i8* %dest, null
|
||||
; CHECK-NOT: icmp
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test7(i8* %dest, i8* %src, i32 %len) {
|
||||
; CHECK: test7
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i32 1, i1 false)
|
||||
br label %bb
|
||||
bb:
|
||||
%KEEP1 = icmp ne i8* %dest, null
|
||||
; CHECK: KEEP1
|
||||
%KEEP2 = icmp ne i8* %src, null
|
||||
; CHECK: KEEP2
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1) *, i8 addrspace(1) *, i32, i32, i1)
|
||||
define void @test8(i8 addrspace(1) * %dest, i8 addrspace(1) * %src) {
|
||||
; CHECK: test8
|
||||
call void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1) * %dest, i8 addrspace(1) * %src, i32 1, i32 1, i1 false)
|
||||
br label %bb
|
||||
bb:
|
||||
%KEEP1 = icmp ne i8 addrspace(1) * %dest, null
|
||||
; CHECK: KEEP1
|
||||
%KEEP2 = icmp ne i8 addrspace(1) * %src, null
|
||||
; CHECK: KEEP2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test9(i8* %dest, i8* %src) {
|
||||
; CHECK: test9
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i32 1, i1 true)
|
||||
br label %bb
|
||||
bb:
|
||||
%KEEP1 = icmp ne i8* %dest, null
|
||||
; CHECK: KEEP1
|
||||
%KEEP2 = icmp ne i8* %src, null
|
||||
; CHECK: KEEP2
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
|
||||
define void @test10(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) {
|
||||
; CHECK-LABEL: @test10
|
||||
entry:
|
||||
%is_null = icmp eq i8* %arg1, null
|
||||
br i1 %is_null, label %null, label %non_null
|
||||
|
||||
non_null:
|
||||
call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
|
||||
; CHECK: call void @test10_helper(i8* nonnull %arg1, i8* %arg2, i32 %non-pointer-arg)
|
||||
br label %null
|
||||
|
||||
null:
|
||||
call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
|
||||
; CHECK: call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @test11_helper(i8* %arg)
|
||||
define void @test11(i8* %arg1, i8** %arg2) {
|
||||
; CHECK-LABEL: @test11
|
||||
entry:
|
||||
%is_null = icmp eq i8* %arg1, null
|
||||
br i1 %is_null, label %null, label %non_null
|
||||
|
||||
non_null:
|
||||
br label %merge
|
||||
|
||||
null:
|
||||
%another_arg = alloca i8
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null]
|
||||
call void @test11_helper(i8* %merged_arg)
|
||||
; CHECK: call void @test11_helper(i8* nonnull %merged_arg)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @test12_helper(i8* %arg)
|
||||
define void @test12(i8* %arg1, i8** %arg2) {
|
||||
; CHECK-LABEL: @test12
|
||||
entry:
|
||||
%is_null = icmp eq i8* %arg1, null
|
||||
br i1 %is_null, label %null, label %non_null
|
||||
|
||||
non_null:
|
||||
br label %merge
|
||||
|
||||
null:
|
||||
%another_arg = load i8*, i8** %arg2, !nonnull !{}
|
||||
br label %merge
|
||||
|
||||
merge:
|
||||
%merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null]
|
||||
call void @test12_helper(i8* %merged_arg)
|
||||
; CHECK: call void @test12_helper(i8* nonnull %merged_arg)
|
||||
ret void
|
||||
}
|
@ -1,368 +0,0 @@
|
||||
; RUN: opt -S -correlated-propagation < %s | FileCheck %s
|
||||
|
||||
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
|
||||
|
||||
declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
|
||||
|
||||
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
|
||||
|
||||
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
|
||||
|
||||
declare void @llvm.trap()
|
||||
|
||||
|
||||
define i32 @signed_add(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @signed_add(
|
||||
; CHECK-NOT: @llvm.ssub.with.overflow.i32
|
||||
; CHECK: @llvm.sadd.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %y, 0
|
||||
br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
|
||||
|
||||
land.lhs.true: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
|
||||
%1 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %1, label %trap, label %cont
|
||||
|
||||
trap: ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cont: ; preds = %land.lhs.true
|
||||
%2 = extractvalue { i32, i1 } %0, 0
|
||||
%cmp1 = icmp slt i32 %2, %x
|
||||
br i1 %cmp1, label %cond.end, label %cond.false
|
||||
|
||||
lor.lhs.false: ; preds = %entry
|
||||
%cmp2 = icmp slt i32 %y, 0
|
||||
br i1 %cmp2, label %land.lhs.true3, label %cond.false
|
||||
|
||||
land.lhs.true3: ; preds = %lor.lhs.false
|
||||
%3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
|
||||
%4 = extractvalue { i32, i1 } %3, 1
|
||||
br i1 %4, label %trap, label %cont4
|
||||
|
||||
cont4: ; preds = %land.lhs.true3
|
||||
%5 = extractvalue { i32, i1 } %3, 0
|
||||
%cmp5 = icmp sgt i32 %5, %x
|
||||
br i1 %cmp5, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %cont, %cont4, %lor.lhs.false
|
||||
%6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
|
||||
%7 = extractvalue { i32, i1 } %6, 0
|
||||
%8 = extractvalue { i32, i1 } %6, 1
|
||||
br i1 %8, label %trap, label %cond.end
|
||||
|
||||
cond.end: ; preds = %cond.false, %cont, %cont4
|
||||
%cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @unsigned_add(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @unsigned_add(
|
||||
; CHECK-NOT: @llvm.usub.with.overflow.i32
|
||||
; CHECK: @llvm.uadd.with.overflow.i32
|
||||
entry:
|
||||
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
|
||||
%1 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %1, label %trap, label %cont
|
||||
|
||||
trap: ; preds = %cond.false, %entry
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cont: ; preds = %entry
|
||||
%2 = extractvalue { i32, i1 } %0, 0
|
||||
%cmp1 = icmp ult i32 %2, %x
|
||||
br i1 %cmp1, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %cont
|
||||
%3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
|
||||
%4 = extractvalue { i32, i1 } %3, 0
|
||||
%5 = extractvalue { i32, i1 } %3, 1
|
||||
br i1 %5, label %trap, label %cond.end
|
||||
|
||||
cond.end: ; preds = %cond.false, %cont
|
||||
%cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @signed_sub(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @signed_sub(
|
||||
; CHECK-NOT: @llvm.sadd.with.overflow.i32
|
||||
; CHECK: @llvm.ssub.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp slt i32 %y, 0
|
||||
br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
|
||||
|
||||
land.lhs.true: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
|
||||
%1 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %1, label %trap, label %cont
|
||||
|
||||
trap: ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cont: ; preds = %land.lhs.true
|
||||
%2 = extractvalue { i32, i1 } %0, 0
|
||||
%cmp1 = icmp slt i32 %2, %x
|
||||
br i1 %cmp1, label %cond.end, label %cond.false
|
||||
|
||||
lor.lhs.false: ; preds = %entry
|
||||
%cmp2 = icmp eq i32 %y, 0
|
||||
br i1 %cmp2, label %cond.false, label %land.lhs.true3
|
||||
|
||||
land.lhs.true3: ; preds = %lor.lhs.false
|
||||
%3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
|
||||
%4 = extractvalue { i32, i1 } %3, 1
|
||||
br i1 %4, label %trap, label %cont4
|
||||
|
||||
cont4: ; preds = %land.lhs.true3
|
||||
%5 = extractvalue { i32, i1 } %3, 0
|
||||
%cmp5 = icmp sgt i32 %5, %x
|
||||
br i1 %cmp5, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %lor.lhs.false, %cont, %cont4
|
||||
%6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
|
||||
%7 = extractvalue { i32, i1 } %6, 0
|
||||
%8 = extractvalue { i32, i1 } %6, 1
|
||||
br i1 %8, label %trap, label %cond.end
|
||||
|
||||
cond.end: ; preds = %cond.false, %cont, %cont4
|
||||
%cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @unsigned_sub(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @unsigned_sub(
|
||||
; CHECK: @llvm.usub.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp ult i32 %x, %y
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @signed_add_r1(i32 %x) {
|
||||
; CHECK-LABEL: @signed_add_r1(
|
||||
; CHECK-NOT: @llvm.sadd.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, 2147483647
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @unsigned_add_r1(i32 %x) {
|
||||
; CHECK-LABEL: @unsigned_add_r1(
|
||||
; CHECK-NOT: @llvm.uadd.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, -1
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @signed_sub_r1(i32 %x) {
|
||||
; CHECK-LABEL: @signed_sub_r1(
|
||||
; CHECK-NOT: @llvm.ssub.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, -2147483648
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @unsigned_sub_r1(i32 %x) {
|
||||
; CHECK-LABEL: @unsigned_sub_r1(
|
||||
; CHECK-NOT: @llvm.usub.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, 0
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @signed_add_rn1(i32 %x) {
|
||||
; CHECK-LABEL: @signed_add_rn1(
|
||||
; CHECK-NOT: @llvm.sadd.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, -2147483648
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
define i32 @signed_sub_rn1(i32 %x) {
|
||||
; CHECK-LABEL: @signed_sub_rn1(
|
||||
; CHECK-NOT: @llvm.ssub.with.overflow.i32
|
||||
entry:
|
||||
%cmp = icmp eq i32 %x, 2147483647
|
||||
br i1 %cmp, label %cond.end, label %cond.false
|
||||
|
||||
cond.false: ; preds = %entry
|
||||
%0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
|
||||
%1 = extractvalue { i32, i1 } %0, 0
|
||||
%2 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %2, label %trap, label %cond.end
|
||||
|
||||
trap: ; preds = %cond.false
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cond.end: ; preds = %cond.false, %entry
|
||||
%cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
declare i32 @bar(i32)
|
||||
|
||||
define void @unsigned_loop(i32 %i) {
|
||||
; CHECK-LABEL: @unsigned_loop(
|
||||
; CHECK-NOT: @llvm.usub.with.overflow.i32
|
||||
entry:
|
||||
%cmp3 = icmp eq i32 %i, 0
|
||||
br i1 %cmp3, label %while.end, label %while.body.preheader
|
||||
|
||||
while.body.preheader: ; preds = %entry
|
||||
br label %while.body
|
||||
|
||||
while.body: ; preds = %while.body.preheader, %cont
|
||||
%i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
|
||||
%call = tail call i32 @bar(i32 %i.addr.04)
|
||||
%0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %1, label %trap, label %cont
|
||||
|
||||
trap: ; preds = %while.body
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cont: ; preds = %while.body
|
||||
%2 = extractvalue { i32, i1 } %0, 0
|
||||
%cmp = icmp eq i32 %2, 0
|
||||
br i1 %cmp, label %while.end, label %while.body
|
||||
|
||||
while.end: ; preds = %cont, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @intrinsic_into_phi(i32 %n) {
|
||||
; CHECK-LABEL: @intrinsic_into_phi(
|
||||
; CHECK: @llvm.sadd.with.overflow.i32
|
||||
; CHECK-NOT: @llvm.sadd.with.overflow.i32
|
||||
entry:
|
||||
br label %cont
|
||||
|
||||
for.cond: ; preds = %while.end
|
||||
%0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
|
||||
%1 = extractvalue { i32, i1 } %0, 1
|
||||
br i1 %1, label %trap, label %cont
|
||||
|
||||
trap: ; preds = %for.cond, %while.body
|
||||
tail call void @llvm.trap()
|
||||
unreachable
|
||||
|
||||
cont: ; preds = %entry, %for.cond
|
||||
%2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
|
||||
%3 = extractvalue { i32, i1 } %2, 0
|
||||
%call9 = tail call i32 @bar(i32 %3)
|
||||
%tobool10 = icmp eq i32 %call9, 0
|
||||
br i1 %tobool10, label %while.end, label %while.body.preheader
|
||||
|
||||
while.body.preheader: ; preds = %cont
|
||||
br label %while.body
|
||||
|
||||
while.cond: ; preds = %while.body
|
||||
%4 = extractvalue { i32, i1 } %6, 0
|
||||
%call = tail call i32 @bar(i32 %4)
|
||||
%tobool = icmp eq i32 %call, 0
|
||||
br i1 %tobool, label %while.end, label %while.body
|
||||
|
||||
while.body: ; preds = %while.body.preheader, %while.cond
|
||||
%5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
|
||||
%6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
|
||||
%7 = extractvalue { i32, i1 } %6, 1
|
||||
br i1 %7, label %trap, label %while.cond
|
||||
|
||||
while.end: ; preds = %while.cond, %cont
|
||||
%.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
|
||||
%cmp = icmp slt i32 %.lcssa, %n
|
||||
br i1 %cmp, label %for.cond, label %cleanup2
|
||||
|
||||
cleanup2: ; preds = %while.end
|
||||
ret void
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test0(
|
||||
define void @test0(i32 %n) {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.body, %entry
|
||||
%j.0 = phi i32 [ %n, %entry ], [ %div, %for.body ]
|
||||
%cmp = icmp sgt i32 %j.0, 1
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
; CHECK: %div1 = udiv i32 %j.0, 2
|
||||
%div = sdiv i32 %j.0, 2
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test1(
|
||||
define void @test1(i32 %n) {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.body, %entry
|
||||
%j.0 = phi i32 [ %n, %entry ], [ %div, %for.body ]
|
||||
%cmp = icmp sgt i32 %j.0, -2
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
; CHECK: %div = sdiv i32 %j.0, 2
|
||||
%div = sdiv i32 %j.0, 2
|
||||
br label %for.cond
|
||||
|
||||
for.end: ; preds = %for.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test2(
|
||||
define void @test2(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 1
|
||||
br i1 %cmp, label %bb, label %exit
|
||||
|
||||
bb:
|
||||
; CHECK: %div1 = udiv i32 %n, 2
|
||||
%div = sdiv i32 %n, 2
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; looping case where loop has exactly one block
|
||||
; at the point of sdiv, we know that %a is always greater than 0,
|
||||
; because of the guard before it, so we can transform it to udiv.
|
||||
declare void @llvm.experimental.guard(i1,...)
|
||||
; CHECK-LABEL: @test4
|
||||
define void @test4(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
loop:
|
||||
; CHECK: udiv i32 %a, 6
|
||||
%a = phi i32 [ %n, %entry ], [ %div, %loop ]
|
||||
%cond = icmp sgt i32 %a, 4
|
||||
call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
|
||||
%div = sdiv i32 %a, 6
|
||||
br i1 %cond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; same test as above with assume instead of guard.
|
||||
declare void @llvm.assume(i1)
|
||||
; CHECK-LABEL: @test5
|
||||
define void @test5(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
loop:
|
||||
; CHECK: udiv i32 %a, 6
|
||||
%a = phi i32 [ %n, %entry ], [ %div, %loop ]
|
||||
%cond = icmp sgt i32 %a, 4
|
||||
call void @llvm.assume(i1 %cond)
|
||||
%div = sdiv i32 %a, 6
|
||||
%loopcond = icmp sgt i32 %div, 8
|
||||
br i1 %loopcond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @simple(
|
||||
define i8 @simple(i1) {
|
||||
entry:
|
||||
%s = select i1 %0, i8 0, i8 1
|
||||
br i1 %0, label %then, label %else
|
||||
|
||||
then:
|
||||
; CHECK: ret i8 0
|
||||
%a = phi i8 [ %s, %entry ]
|
||||
ret i8 %a
|
||||
|
||||
else:
|
||||
; CHECK: ret i8 1
|
||||
%b = phi i8 [ %s, %entry ]
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @loop(
|
||||
define void @loop(i32) {
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
%idx = phi i32 [ %0, %entry ], [ %sel, %loop ]
|
||||
; CHECK: %idx = phi i32 [ %0, %entry ], [ %2, %loop ]
|
||||
%1 = icmp eq i32 %idx, 0
|
||||
%2 = add i32 %idx, -1
|
||||
%sel = select i1 %1, i32 0, i32 %2
|
||||
br i1 %1, label %out, label %loop
|
||||
|
||||
out:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @not_correlated(
|
||||
define i8 @not_correlated(i1, i1) {
|
||||
entry:
|
||||
%s = select i1 %0, i8 0, i8 1
|
||||
br i1 %1, label %then, label %else
|
||||
|
||||
then:
|
||||
; CHECK: ret i8 %s
|
||||
%a = phi i8 [ %s, %entry ]
|
||||
ret i8 %a
|
||||
|
||||
else:
|
||||
; CHECK: ret i8 %s
|
||||
%b = phi i8 [ %s, %entry ]
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
@c = global i32 0, align 4
|
||||
@b = global i32 0, align 4
|
||||
|
||||
; CHECK-LABEL: @PR23752(
|
||||
define i32 @PR23752() {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body:
|
||||
%phi = phi i32 [ 0, %entry ], [ %sel, %for.body ]
|
||||
%sel = select i1 icmp sgt (i32* @b, i32* @c), i32 %phi, i32 1
|
||||
%cmp = icmp ne i32 %sel, 1
|
||||
br i1 %cmp, label %for.body, label %if.end
|
||||
|
||||
; CHECK: %[[sel:.*]] = select i1 icmp sgt (i32* @b, i32* @c), i32 0, i32 1
|
||||
; CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[sel]], 1
|
||||
; CHECK-NEXT: br i1 %[[cmp]]
|
||||
|
||||
if.end:
|
||||
ret i32 %sel
|
||||
; CHECK: ret i32 1
|
||||
}
|
||||
|
||||
define i1 @test1(i32* %p, i1 %unknown) {
|
||||
; CHECK-LABEL: @test1
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp slt i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%min = select i1 %unknown, i32 %pval, i32 5
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2:
|
||||
; CHECK: ret i1 false
|
||||
%res = icmp eq i32 %min, 255
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
||||
|
||||
; Check that we take a conservative meet
|
||||
define i1 @test2(i32* %p, i32 %qval, i1 %unknown) {
|
||||
; CHECK-LABEL: test2
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp slt i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%min = select i1 %unknown, i32 %pval, i32 %qval
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2
|
||||
; CHECK: ret i1 %res
|
||||
%res = icmp eq i32 %min, 255
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
||||
|
||||
; Same as @test2, but for the opposite select input
|
||||
define i1 @test3(i32* %p, i32 %qval, i1 %unknown) {
|
||||
; CHECK-LABEL: test3
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp slt i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%min = select i1 %unknown, i32 %qval, i32 %pval
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2
|
||||
; CHECK: ret i1 %res
|
||||
%res = icmp eq i32 %min, 255
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
||||
|
||||
; Conflicting constants (i.e. isOverdefined result)
|
||||
; NOTE: Using doubles in this version is a bit of a hack. This
|
||||
; is to get around the fact that all integers (including constants
|
||||
; and non-constants) are actually represented as constant-ranges.
|
||||
define i1 @test4(i32* %p, i32 %qval, i1 %unknown) {
|
||||
; CHECK-LABEL: test4
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp slt i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%min = select i1 %unknown, double 1.0, double 0.0
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2
|
||||
; CHECK: ret i1 %res
|
||||
%res = fcmp oeq double %min, 300.0
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
||||
|
||||
;; Using the condition to clamp the result
|
||||
;;
|
||||
|
||||
define i1 @test5(i32* %p, i1 %unknown) {
|
||||
; CHECK-LABEL: @test5
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp slt i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%cond = icmp sgt i32 %pval, 0
|
||||
%min = select i1 %cond, i32 %pval, i32 5
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2:
|
||||
; CHECK: ret i1 false
|
||||
%res = icmp eq i32 %min, -1
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
||||
|
||||
define i1 @test6(i32* %p, i1 %unknown) {
|
||||
; CHECK-LABEL: @test6
|
||||
%pval = load i32, i32* %p
|
||||
%cmp1 = icmp ult i32 %pval, 255
|
||||
br i1 %cmp1, label %next, label %exit
|
||||
|
||||
next:
|
||||
%cond = icmp ne i32 %pval, 254
|
||||
%sel = select i1 %cond, i32 %pval, i32 1
|
||||
;; TODO: This pointless branch shouldn't be neccessary
|
||||
br label %next2
|
||||
next2:
|
||||
; CHECK-LABEL: next2:
|
||||
; CHECK: ret i1 true
|
||||
%res = icmp slt i32 %sel, 254
|
||||
ret i1 %res
|
||||
|
||||
exit:
|
||||
; CHECK-LABEL: exit:
|
||||
; CHECK: ret i1 true
|
||||
ret i1 true
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
; RUN: opt < %s -correlated-propagation -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
target triple = "thumbv7m-arm-none-eabi"
|
||||
|
||||
define void @h(i32* nocapture %p, i32 %x) local_unnamed_addr #0 {
|
||||
entry:
|
||||
; CHECK-LABEL: @h(
|
||||
; CHECK: urem
|
||||
|
||||
%cmp = icmp sgt i32 %x, 0
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
%rem2 = srem i32 %x, 10
|
||||
store i32 %rem2, i32* %p, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; looping case where loop has exactly one block
|
||||
; at the point of srem, we know that %a is always greater than 0,
|
||||
; because of the assume before it, so we can transform it to urem.
|
||||
declare void @llvm.assume(i1)
|
||||
; CHECK-LABEL: @test4
|
||||
define void @test4(i32 %n) {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %n, 0
|
||||
br i1 %cmp, label %loop, label %exit
|
||||
|
||||
loop:
|
||||
; CHECK: urem i32 %a, 6
|
||||
%a = phi i32 [ %n, %entry ], [ %rem, %loop ]
|
||||
%cond = icmp sgt i32 %a, 4
|
||||
call void @llvm.assume(i1 %cond)
|
||||
%rem = srem i32 %a, 6
|
||||
%loopcond = icmp sgt i32 %rem, 8
|
||||
br i1 %loopcond, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
Reference in New Issue
Block a user