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,13 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -S | grep "ret i32 0"
|
||||
; PR3138
|
||||
|
||||
define i32 @jt() {
|
||||
entry:
|
||||
br i1 true, label %bb3, label %bb
|
||||
|
||||
bb: ; preds = %entry
|
||||
unreachable
|
||||
|
||||
bb3: ; preds = %entry
|
||||
ret i32 0
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
; RUN: opt -jump-threading -S < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
||||
%class.StringSwitch = type { i8*, i32, i32, i8 }
|
||||
|
||||
@.str = private constant [4 x i8] c"red\00" ; <[4 x i8]*> [#uses=1]
|
||||
@.str1 = private constant [7 x i8] c"orange\00" ; <[7 x i8]*> [#uses=1]
|
||||
@.str2 = private constant [7 x i8] c"yellow\00" ; <[7 x i8]*> [#uses=1]
|
||||
@.str3 = private constant [6 x i8] c"green\00" ; <[6 x i8]*> [#uses=1]
|
||||
@.str4 = private constant [5 x i8] c"blue\00" ; <[5 x i8]*> [#uses=1]
|
||||
@.str5 = private constant [7 x i8] c"indigo\00" ; <[7 x i8]*> [#uses=1]
|
||||
@.str6 = private constant [7 x i8] c"violet\00" ; <[7 x i8]*> [#uses=1]
|
||||
@.str7 = private constant [12 x i8] c"Color = %d\0A\00" ; <[12 x i8]*> [#uses=1]
|
||||
|
||||
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind ssp {
|
||||
entry:
|
||||
%cmp142 = icmp sgt i32 %argc, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp142, label %bb.nph, label %for.end
|
||||
|
||||
bb.nph: ; preds = %entry
|
||||
%tmp = add i32 %argc, -2 ; <i32> [#uses=1]
|
||||
%tmp144 = zext i32 %tmp to i64 ; <i64> [#uses=1]
|
||||
%tmp145 = add i64 %tmp144, 1 ; <i64> [#uses=1]
|
||||
br label %land.lhs.true.i
|
||||
|
||||
land.lhs.true.i: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134, %bb.nph
|
||||
%retval.0.i.pre161 = phi i32 [ undef, %bb.nph ], [ %retval.0.i.pre, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134 ] ; <i32> [#uses=3]
|
||||
%indvar = phi i64 [ 0, %bb.nph ], [ %tmp146, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134 ] ; <i64> [#uses=1]
|
||||
%tmp146 = add i64 %indvar, 1 ; <i64> [#uses=3]
|
||||
%arrayidx = getelementptr i8*, i8** %argv, i64 %tmp146 ; <i8**> [#uses=1]
|
||||
%tmp6 = load i8*, i8** %arrayidx, align 8 ; <i8*> [#uses=8]
|
||||
%call.i.i = call i64 @strlen(i8* %tmp6) nounwind ; <i64> [#uses=1]
|
||||
%conv.i.i = trunc i64 %call.i.i to i32 ; <i32> [#uses=6]\
|
||||
; CHECK: switch i32 %conv.i.i
|
||||
; CHECK-NOT: if.then.i40
|
||||
; CHECK: }
|
||||
switch i32 %conv.i.i, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit [
|
||||
i32 3, label %land.lhs.true5.i
|
||||
i32 6, label %land.lhs.true5.i37
|
||||
]
|
||||
|
||||
land.lhs.true5.i: ; preds = %land.lhs.true.i
|
||||
%call.i = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* %tmp6, i64 4) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i = icmp eq i32 %call.i, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i, label %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit: ; preds = %land.lhs.true5.i
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
land.lhs.true5.i37: ; preds = %land.lhs.true.i
|
||||
%call.i35 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str1, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i36 = icmp eq i32 %call.i35, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i36, label %if.then.i40, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
if.then.i40: ; preds = %land.lhs.true5.i37
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i40, %land.lhs.true5.i37, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit, %land.lhs.true5.i, %land.lhs.true.i
|
||||
%retval.0.i.pre159 = phi i32 [ 1, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre161, %land.lhs.true5.i37 ], [ 2, %if.then.i40 ], [ %retval.0.i.pre161, %land.lhs.true5.i ], [ %retval.0.i.pre161, %land.lhs.true.i ] ; <i32> [#uses=2]
|
||||
%tmp2.i44 = phi i8 [ 1, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit ], [ 0, %land.lhs.true5.i37 ], [ 1, %if.then.i40 ], [ 0, %land.lhs.true5.i ], [ 0, %land.lhs.true.i ] ; <i8> [#uses=3]
|
||||
%tobool.i46 = icmp eq i8 %tmp2.i44, 0 ; <i1> [#uses=1]
|
||||
%cmp.i49 = icmp eq i32 %conv.i.i, 6 ; <i1> [#uses=1]
|
||||
%or.cond = and i1 %tobool.i46, %cmp.i49 ; <i1> [#uses=1]
|
||||
br i1 %or.cond, label %land.lhs.true5.i55, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
|
||||
|
||||
land.lhs.true5.i55: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
%call.i53 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str2, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i54 = icmp eq i32 %call.i53, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i54, label %if.then.i58, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
|
||||
|
||||
if.then.i58: ; preds = %land.lhs.true5.i55
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60: ; preds = %if.then.i58, %land.lhs.true5.i55, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
|
||||
%retval.0.i.pre158 = phi i32 [ %retval.0.i.pre159, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre159, %land.lhs.true5.i55 ], [ 3, %if.then.i58 ] ; <i32> [#uses=2]
|
||||
%tmp2.i63 = phi i8 [ %tmp2.i44, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i44, %land.lhs.true5.i55 ], [ 1, %if.then.i58 ] ; <i8> [#uses=3]
|
||||
%tmp14.i64 = and i8 %tmp2.i63, 1 ; <i8> [#uses=1]
|
||||
%tobool.i65 = icmp eq i8 %tmp14.i64, 0 ; <i1> [#uses=1]
|
||||
%cmp.i68 = icmp eq i32 %conv.i.i, 5 ; <i1> [#uses=1]
|
||||
%or.cond168 = and i1 %tobool.i65, %cmp.i68 ; <i1> [#uses=1]
|
||||
br i1 %or.cond168, label %land.lhs.true5.i74, label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
land.lhs.true5.i74: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
|
||||
%call.i72 = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str3, i64 0, i64 0), i8* %tmp6, i64 6) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i73 = icmp eq i32 %call.i72, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i73, label %if.then.i77, label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
if.then.i77: ; preds = %land.lhs.true5.i74
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i77, %land.lhs.true5.i74, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
|
||||
%retval.0.i.pre157 = phi i32 [ %retval.0.i.pre158, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60 ], [ %retval.0.i.pre158, %land.lhs.true5.i74 ], [ 4, %if.then.i77 ] ; <i32> [#uses=2]
|
||||
%tmp2.i81 = phi i8 [ %tmp2.i63, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60 ], [ %tmp2.i63, %land.lhs.true5.i74 ], [ 1, %if.then.i77 ] ; <i8> [#uses=3]
|
||||
%tmp14.i82 = and i8 %tmp2.i81, 1 ; <i8> [#uses=1]
|
||||
%tobool.i83 = icmp eq i8 %tmp14.i82, 0 ; <i1> [#uses=1]
|
||||
%cmp.i86 = icmp eq i32 %conv.i.i, 4 ; <i1> [#uses=1]
|
||||
%or.cond169 = and i1 %tobool.i83, %cmp.i86 ; <i1> [#uses=1]
|
||||
br i1 %or.cond169, label %land.lhs.true5.i92, label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
land.lhs.true5.i92: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
|
||||
%call.i90 = call i32 @memcmp(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str4, i64 0, i64 0), i8* %tmp6, i64 5) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i91 = icmp eq i32 %call.i90, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i91, label %if.then.i95, label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
if.then.i95: ; preds = %land.lhs.true5.i92
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i95, %land.lhs.true5.i92, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
|
||||
%retval.0.i.pre156 = phi i32 [ %retval.0.i.pre157, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre157, %land.lhs.true5.i92 ], [ 5, %if.then.i95 ] ; <i32> [#uses=2]
|
||||
%tmp2.i99 = phi i8 [ %tmp2.i81, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i81, %land.lhs.true5.i92 ], [ 1, %if.then.i95 ] ; <i8> [#uses=3]
|
||||
%tmp14.i100 = and i8 %tmp2.i99, 1 ; <i8> [#uses=1]
|
||||
%tobool.i101 = icmp eq i8 %tmp14.i100, 0 ; <i1> [#uses=1]
|
||||
%cmp.i104 = icmp eq i32 %conv.i.i, 6 ; <i1> [#uses=1]
|
||||
%or.cond170 = and i1 %tobool.i101, %cmp.i104 ; <i1> [#uses=1]
|
||||
br i1 %or.cond170, label %land.lhs.true5.i110, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
|
||||
|
||||
land.lhs.true5.i110: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
|
||||
%call.i108 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str5, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i109 = icmp eq i32 %call.i108, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i109, label %if.then.i113, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
|
||||
|
||||
if.then.i113: ; preds = %land.lhs.true5.i110
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115: ; preds = %if.then.i113, %land.lhs.true5.i110, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
|
||||
%retval.0.i.pre155 = phi i32 [ %retval.0.i.pre156, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre156, %land.lhs.true5.i110 ], [ 6, %if.then.i113 ] ; <i32> [#uses=2]
|
||||
%tmp2.i118 = phi i8 [ %tmp2.i99, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i99, %land.lhs.true5.i110 ], [ 1, %if.then.i113 ] ; <i8> [#uses=3]
|
||||
%tmp14.i119 = and i8 %tmp2.i118, 1 ; <i8> [#uses=1]
|
||||
%tobool.i120 = icmp eq i8 %tmp14.i119, 0 ; <i1> [#uses=1]
|
||||
%cmp.i123 = icmp eq i32 %conv.i.i, 6 ; <i1> [#uses=1]
|
||||
%or.cond171 = and i1 %tobool.i120, %cmp.i123 ; <i1> [#uses=1]
|
||||
br i1 %or.cond171, label %land.lhs.true5.i129, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
|
||||
|
||||
land.lhs.true5.i129: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
|
||||
%call.i127 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str6, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; <i32> [#uses=1]
|
||||
%cmp9.i128 = icmp eq i32 %call.i127, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp9.i128, label %if.then.i132, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
|
||||
|
||||
if.then.i132: ; preds = %land.lhs.true5.i129
|
||||
br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
|
||||
|
||||
_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134: ; preds = %if.then.i132, %land.lhs.true5.i129, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
|
||||
%retval.0.i.pre = phi i32 [ %retval.0.i.pre155, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115 ], [ %retval.0.i.pre155, %land.lhs.true5.i129 ], [ 7, %if.then.i132 ] ; <i32> [#uses=2]
|
||||
%tmp2.i137 = phi i8 [ %tmp2.i118, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115 ], [ %tmp2.i118, %land.lhs.true5.i129 ], [ 1, %if.then.i132 ] ; <i8> [#uses=1]
|
||||
%tmp7.i138 = and i8 %tmp2.i137, 1 ; <i8> [#uses=1]
|
||||
%tobool.i139 = icmp eq i8 %tmp7.i138, 0 ; <i1> [#uses=1]
|
||||
%retval.0.i = select i1 %tobool.i139, i32 0, i32 %retval.0.i.pre ; <i32> [#uses=1]
|
||||
%call22 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str7, i64 0, i64 0), i32 %retval.0.i) ; <i32> [#uses=0]
|
||||
%exitcond = icmp eq i64 %tmp146, %tmp145 ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %for.end, label %land.lhs.true.i
|
||||
|
||||
for.end: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134, %entry
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8* nocapture, ...) nounwind
|
||||
|
||||
declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) nounwind readonly
|
||||
|
||||
declare i64 @strlen(i8* nocapture) nounwind readonly
|
@ -1,32 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading
|
||||
; PR9446
|
||||
; Just check that it doesn't crash
|
||||
|
||||
define void @int327() nounwind {
|
||||
entry:
|
||||
unreachable
|
||||
|
||||
for.cond: ; preds = %for.cond4
|
||||
%tobool3 = icmp eq i8 undef, 0
|
||||
br i1 %tobool3, label %for.cond23, label %for.cond4
|
||||
|
||||
for.cond4: ; preds = %for.cond
|
||||
br label %for.cond
|
||||
|
||||
for.cond23: ; preds = %for.body28, %for.cond23, %for.cond
|
||||
%conv321 = phi i32 [ %conv32, %for.body28 ], [ 0, %for.cond ], [ %conv321, %for.cond23 ]
|
||||
%l_266.0 = phi i32 [ %phitmp, %for.body28 ], [ 0, %for.cond ], [ 0, %for.cond23 ]
|
||||
%cmp26 = icmp eq i32 %l_266.0, 0
|
||||
br i1 %cmp26, label %for.body28, label %for.cond23
|
||||
|
||||
for.body28: ; preds = %for.cond23
|
||||
%and = and i32 %conv321, 1
|
||||
%conv32 = zext i8 undef to i32
|
||||
%add = add nsw i32 %l_266.0, 1
|
||||
%phitmp = and i32 %add, 255
|
||||
br label %for.cond23
|
||||
|
||||
if.end43: ; No predecessors!
|
||||
ret void
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
; RUN: opt -jump-threading < %s
|
||||
; <rdar://problem/9284786>
|
||||
|
||||
%0 = type <{ i64, i16, i64, i8, i8 }>
|
||||
|
||||
@g_338 = external global %0, align 8
|
||||
|
||||
define void @func_1() nounwind ssp {
|
||||
entry:
|
||||
ret void
|
||||
|
||||
for.cond1177:
|
||||
%inc1187 = add nsw i32 0, 1
|
||||
%cmp1179 = icmp slt i32 %inc1187, 5
|
||||
br i1 %cmp1179, label %for.cond1177, label %land.rhs1320
|
||||
|
||||
land.rhs1320:
|
||||
%tmp1324 = load volatile i64, i64* getelementptr inbounds (%0, %0* @g_338, i64 0, i32 2), align 1
|
||||
br label %if.end.i
|
||||
|
||||
if.end.i:
|
||||
%tobool.pr.i = phi i1 [ false, %if.end.i ], [ false, %land.rhs1320 ]
|
||||
br i1 %tobool.pr.i, label %return, label %if.end.i
|
||||
|
||||
return:
|
||||
ret void
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading
|
||||
; PR 13405
|
||||
; Just check that it doesn't crash / assert
|
||||
|
||||
define i32 @f() nounwind {
|
||||
entry:
|
||||
indirectbr i8* undef, []
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | FileCheck %s
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
declare void @f3()
|
||||
|
||||
define i32 @test(i1 %cond, i1 %cond2, i1 %cond3) {
|
||||
; CHECK: test
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
; CHECK-NOT: T1:
|
||||
T1:
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge:
|
||||
; CHECK: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: %D = and i1 %cond2, %cond3
|
||||
; CHECK-NEXT: br i1 %D
|
||||
%A = phi i1 [true, %T1], [false, %F1]
|
||||
%B = phi i32 [%v1, %T1], [%v2, %F1]
|
||||
%C = and i1 %A, %cond2
|
||||
%D = and i1 %C, %cond3
|
||||
br i1 %D, label %T2, label %F2
|
||||
|
||||
T2:
|
||||
call void @f3()
|
||||
ret i32 %B
|
||||
|
||||
F2:
|
||||
ret i32 %B
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -mem2reg -instcombine -simplifycfg -S | FileCheck %s
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
declare void @f3()
|
||||
|
||||
define i32 @test(i1 %cond, i1 %cond2) {
|
||||
; CHECK: test
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
; CHECK-NOT: T1
|
||||
T1:
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge:
|
||||
; CHECK: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: br i1 %cond2
|
||||
%A = phi i1 [true, %T1], [false, %F1]
|
||||
%B = phi i32 [%v1, %T1], [%v2, %F1]
|
||||
%C = and i1 %A, %cond2
|
||||
br i1 %C, label %T2, label %F2
|
||||
|
||||
T2:
|
||||
call void @f3()
|
||||
ret i32 %B
|
||||
|
||||
F2:
|
||||
ret i32 %B
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
; RUN: opt -S -jump-threading < %s | FileCheck %s
|
||||
|
||||
declare i8* @escape()
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
define i1 @test1(i1 %cond) {
|
||||
entry:
|
||||
br i1 %cond, label %taken, label %not_taken
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: br i1 %cond, label %no, label %yes
|
||||
; CHECK: ret i1 true
|
||||
|
||||
taken:
|
||||
%res1 = call i8* @escape()
|
||||
%a = icmp eq i8* %res1, null
|
||||
tail call void @llvm.assume(i1 %a)
|
||||
br label %done
|
||||
not_taken:
|
||||
%res2 = call i8* @escape()
|
||||
%b = icmp ne i8* %res2, null
|
||||
tail call void @llvm.assume(i1 %b)
|
||||
br label %done
|
||||
|
||||
; An assume that can be used to simplify this comparison dominates each
|
||||
; predecessor branch (although no assume dominates the cmp itself). Make sure
|
||||
; this still can be simplified.
|
||||
|
||||
done:
|
||||
%res = phi i8* [ %res1, %taken ], [ %res2, %not_taken ]
|
||||
%cnd = icmp ne i8* %res, null
|
||||
br i1 %cnd, label %yes, label %no
|
||||
|
||||
yes:
|
||||
ret i1 true
|
||||
no:
|
||||
ret i1 false
|
||||
}
|
||||
|
@ -1,241 +0,0 @@
|
||||
; RUN: opt -S -jump-threading -dce < %s | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define i32 @test1(i32 %a, i32 %b) #0 {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 5
|
||||
tail call void @llvm.assume(i1 %cmp)
|
||||
%cmp1 = icmp sgt i32 %b, 1234
|
||||
br i1 %cmp1, label %if.then, label %if.else
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: icmp sgt i32 %a, 5
|
||||
; CHECK: call void @llvm.assume
|
||||
; CHECK-NOT: icmp sgt i32 %a, 3
|
||||
; CHECK: ret i32
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%cmp2 = icmp sgt i32 %a, 3
|
||||
br i1 %cmp2, label %if.then3, label %return
|
||||
|
||||
if.then3: ; preds = %if.then
|
||||
tail call void (...) @bar() #1
|
||||
br label %return
|
||||
|
||||
if.else: ; preds = %entry
|
||||
tail call void (...) @car() #1
|
||||
br label %return
|
||||
|
||||
return: ; preds = %if.else, %if.then, %if.then3
|
||||
%retval.0 = phi i32 [ 1, %if.then3 ], [ 0, %if.then ], [ 0, %if.else ]
|
||||
ret i32 %retval.0
|
||||
}
|
||||
|
||||
define i32 @test2(i32 %a) #0 {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 5
|
||||
tail call void @llvm.assume(i1 %cmp)
|
||||
%cmp1 = icmp sgt i32 %a, 3
|
||||
br i1 %cmp1, label %if.then, label %return
|
||||
|
||||
; CHECK-LABEL: @test2
|
||||
; CHECK: icmp sgt i32 %a, 5
|
||||
; CHECK: tail call void @llvm.assume
|
||||
; CHECK: tail call void (...) @bar()
|
||||
; CHECK: ret i32 1
|
||||
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void (...) @bar() #1
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry, %if.then
|
||||
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %entry ]
|
||||
ret i32 %retval.0
|
||||
}
|
||||
|
||||
@g = external global i32
|
||||
|
||||
; Check that we do prove a fact using an assume within the block.
|
||||
; We can fold the assume based on the semantics of assume.
|
||||
define void @can_fold_assume(i32* %array) {
|
||||
; CHECK-LABEL: @can_fold_assume
|
||||
; CHECK-NOT: call void @llvm.assume
|
||||
; CHECK-NOT: br
|
||||
; CHECK: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @f(i1)
|
||||
declare void @exit()
|
||||
; We can fold the assume but not the uses before the assume.
|
||||
define void @cannot_fold_use_before_assume(i32* %array) {
|
||||
; CHECK-LABEL:@cannot_fold_use_before_assume
|
||||
; CHECK: @f(i1 %notnull)
|
||||
; CHECK-NEXT: exit()
|
||||
; CHECK-NOT: assume
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @f(i1 %notnull)
|
||||
call void @exit()
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @dummy(i1) nounwind argmemonly
|
||||
define void @can_fold_some_use_before_assume(i32* %array) {
|
||||
|
||||
; CHECK-LABEL:@can_fold_some_use_before_assume
|
||||
; CHECK: @f(i1 %notnull)
|
||||
; CHECK-NEXT: @dummy(i1 true)
|
||||
; CHECK-NOT: assume
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @f(i1 %notnull)
|
||||
call void @dummy(i1 %notnull)
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
|
||||
}
|
||||
|
||||
; FIXME: can fold assume and all uses before/after assume.
|
||||
; because the trapping exit call is after the assume.
|
||||
define void @can_fold_assume_and_all_uses(i32* %array) {
|
||||
; CHECK-LABEL:@can_fold_assume_and_all_uses
|
||||
; CHECK: @dummy(i1 %notnull)
|
||||
; CHECK-NEXT: assume(i1 %notnull)
|
||||
; CHECK-NEXT: exit()
|
||||
; CHECK-NEXT: %notnull2 = or i1 true, false
|
||||
; CHECK-NEXT: @f(i1 %notnull2)
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @dummy(i1 %notnull)
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
call void @exit()
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
%notnull2 = or i1 %notnull, false
|
||||
call void @f(i1 %notnull2)
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @fz(i8)
|
||||
; FIXME: We can fold assume to true, and the use after assume, but we do not do so
|
||||
; currently, because of the function call after the assume.
|
||||
define void @can_fold_assume2(i32* %array) {
|
||||
|
||||
; CHECK-LABEL:@can_fold_assume2
|
||||
; CHECK: @f(i1 %notnull)
|
||||
; CHECK-NEXT: assume(i1 %notnull)
|
||||
; CHECK-NEXT: znotnull = zext i1 %notnull to i8
|
||||
; CHECK-NEXT: @f(i1 %notnull)
|
||||
; CHECK-NEXT: @f(i1 true)
|
||||
; CHECK-NEXT: @fz(i8 %znotnull)
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @f(i1 %notnull)
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
%znotnull = zext i1 %notnull to i8
|
||||
call void @f(i1 %notnull)
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
call void @f(i1 %notnull)
|
||||
call void @fz(i8 %znotnull)
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
; FIXME: We can fold assume to true, but we do not do so
|
||||
; because of the guard following the assume.
|
||||
define void @can_fold_assume3(i32* %array){
|
||||
|
||||
; CHECK-LABEL:@can_fold_assume3
|
||||
; CHECK: @f(i1 %notnull)
|
||||
; CHECK-NEXT: assume(i1 %notnull)
|
||||
; CHECK-NEXT: guard(i1 %notnull)
|
||||
; CHECK-NEXT: znotnull = zext i1 true to i8
|
||||
; CHECK-NEXT: @f(i1 true)
|
||||
; CHECK-NEXT: @fz(i8 %znotnull)
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @f(i1 %notnull)
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %notnull) [ "deopt"() ]
|
||||
%znotnull = zext i1 %notnull to i8
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
call void @f(i1 %notnull)
|
||||
call void @fz(i8 %znotnull)
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; can fold all uses and remove the cond
|
||||
define void @can_fold_assume4(i32* %array) {
|
||||
; CHECK-LABEL: can_fold_assume4
|
||||
; CHECK-NOT: notnull
|
||||
; CHECK: dummy(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
%notnull = icmp ne i32* %array, null
|
||||
call void @exit()
|
||||
call void @dummy(i1 %notnull)
|
||||
call void @llvm.assume(i1 %notnull)
|
||||
br i1 %notnull, label %normal, label %error
|
||||
|
||||
normal:
|
||||
ret void
|
||||
|
||||
error:
|
||||
store atomic i32 0, i32* @g unordered, align 4
|
||||
ret void
|
||||
}
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.assume(i1) #1
|
||||
|
||||
declare void @bar(...)
|
||||
|
||||
declare void @car(...)
|
||||
|
||||
attributes #0 = { nounwind uwtable }
|
||||
attributes #1 = { nounwind }
|
||||
|
582
external/llvm/test/Transforms/JumpThreading/basic.ll
vendored
582
external/llvm/test/Transforms/JumpThreading/basic.ll
vendored
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -S | not grep phi
|
||||
|
||||
declare i8 @mcguffin()
|
||||
|
||||
define i32 @test(i1 %foo, i8 %b) {
|
||||
entry:
|
||||
%a = call i8 @mcguffin()
|
||||
br i1 %foo, label %bb1, label %bb2
|
||||
bb1:
|
||||
br label %jt
|
||||
bb2:
|
||||
br label %jt
|
||||
jt:
|
||||
%x = phi i8 [%a, %bb1], [%b, %bb2]
|
||||
%A = icmp eq i8 %x, %a
|
||||
br i1 %A, label %rt, label %rf
|
||||
rt:
|
||||
ret i32 7
|
||||
rf:
|
||||
ret i32 8
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
; There should be no phi nodes left.
|
||||
; RUN: opt < %s -jump-threading -S | not grep "phi i32"
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
declare void @f3()
|
||||
|
||||
define i32 @test(i1 %cond) {
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
%B = phi i32 [%v1, %T1], [12, %F1]
|
||||
%A = icmp ne i32 %B, 42
|
||||
br i1 %A, label %T2, label %F2
|
||||
|
||||
T2:
|
||||
call void @f3()
|
||||
ret i32 1
|
||||
|
||||
F2:
|
||||
ret i32 0
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
; RUN: opt -jump-threading -S %s | FileCheck %s
|
||||
|
||||
; Check that we thread arg2neg -> checkpos -> end.
|
||||
;
|
||||
; LazyValueInfo would previously fail to analyze the value of %arg in arg2neg
|
||||
; because its predecessing blocks (checkneg) hadn't been processed yet (PR21238)
|
||||
|
||||
; CHECK-LABEL: @test_jump_threading
|
||||
; CHECK: arg2neg:
|
||||
; CHECK-NEXT: br i1 %arg1, label %end, label %checkpos.thread
|
||||
; CHECK: checkpos.thread:
|
||||
; CHECK-NEXT: br label %end
|
||||
|
||||
define i32 @test_jump_threading(i1 %arg1, i32 %arg2) {
|
||||
checkneg:
|
||||
%cmp = icmp slt i32 %arg2, 0
|
||||
br i1 %cmp, label %arg2neg, label %checkpos
|
||||
|
||||
arg2neg:
|
||||
br i1 %arg1, label %end, label %checkpos
|
||||
|
||||
checkpos:
|
||||
%cmp2 = icmp sgt i32 %arg2, 0
|
||||
br i1 %cmp2, label %arg2pos, label %end
|
||||
|
||||
arg2pos:
|
||||
br label %end
|
||||
|
||||
end:
|
||||
%0 = phi i32 [ 1, %arg2neg ], [ 2, %checkpos ], [ 3, %arg2pos ]
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
|
||||
; arg2neg has an edge back to itself. If LazyValueInfo is not careful when
|
||||
; visiting predecessors, it could get into an infinite loop.
|
||||
|
||||
; CHECK-LABEL: test_infinite_loop
|
||||
|
||||
define i32 @test_infinite_loop(i1 %arg1, i32 %arg2) {
|
||||
checkneg:
|
||||
%cmp = icmp slt i32 %arg2, 0
|
||||
br i1 %cmp, label %arg2neg, label %checkpos
|
||||
|
||||
arg2neg:
|
||||
br i1 %arg1, label %arg2neg, label %checkpos
|
||||
|
||||
checkpos:
|
||||
%cmp2 = icmp sgt i32 %arg2, 0
|
||||
br i1 %cmp2, label %arg2pos, label %end
|
||||
|
||||
arg2pos:
|
||||
br label %end
|
||||
|
||||
end:
|
||||
%0 = phi i32 [ 2, %checkpos ], [ 3, %arg2pos ]
|
||||
ret i32 %0
|
||||
}
|
566
external/llvm/test/Transforms/JumpThreading/crash.ll
vendored
566
external/llvm/test/Transforms/JumpThreading/crash.ll
vendored
File diff suppressed because it is too large
Load Diff
@ -1,43 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -disable-output -verify-dom-info
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@global = external local_unnamed_addr global i64, align 8
|
||||
@global.1 = external local_unnamed_addr global i64, align 8
|
||||
@global.2 = external local_unnamed_addr global i64, align 8
|
||||
|
||||
; Function Attrs: norecurse noreturn nounwind uwtable
|
||||
define void @hoge() local_unnamed_addr #0 {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb26, %bb
|
||||
%tmp = load i64, i64* @global, align 8, !tbaa !1
|
||||
%tmp2 = icmp eq i64 %tmp, 0
|
||||
br i1 %tmp2, label %bb27, label %bb3
|
||||
|
||||
bb3: ; preds = %bb1
|
||||
%tmp4 = load i64, i64* @global.1, align 8, !tbaa !1
|
||||
%tmp5 = icmp eq i64 %tmp4, 0
|
||||
br i1 %tmp5, label %bb23, label %bb23
|
||||
|
||||
bb23: ; preds = %bb3, %bb3
|
||||
br label %bb26
|
||||
|
||||
bb26: ; preds = %bb27, %bb23
|
||||
br label %bb1
|
||||
|
||||
bb27: ; preds = %bb1
|
||||
br label %bb26
|
||||
}
|
||||
|
||||
attributes #0 = { norecurse noreturn nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 7.0.0 "}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"long", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
@ -1,75 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -disable-output -verify-dom-info
|
||||
@global = external global i64, align 8
|
||||
|
||||
define void @f() {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1:
|
||||
%tmp = load i64, i64* @global, align 8
|
||||
%tmp2 = icmp eq i64 %tmp, 0
|
||||
br i1 %tmp2, label %bb27, label %bb3
|
||||
|
||||
bb3:
|
||||
%tmp4 = load i64, i64* @global, align 8
|
||||
%tmp5 = icmp eq i64 %tmp4, 0
|
||||
br i1 %tmp5, label %bb6, label %bb7
|
||||
|
||||
bb6:
|
||||
br label %bb7
|
||||
|
||||
bb7:
|
||||
%tmp8 = phi i1 [ true, %bb3 ], [ undef, %bb6 ]
|
||||
%tmp9 = select i1 %tmp8, i64 %tmp4, i64 0
|
||||
br i1 false, label %bb10, label %bb23
|
||||
|
||||
bb10:
|
||||
%tmp11 = load i64, i64* @global, align 8
|
||||
%tmp12 = icmp slt i64 %tmp11, 5
|
||||
br i1 %tmp12, label %bb13, label %bb17
|
||||
|
||||
bb13:
|
||||
br label %bb14
|
||||
|
||||
bb14:
|
||||
br i1 undef, label %bb15, label %bb16
|
||||
|
||||
bb15:
|
||||
unreachable
|
||||
|
||||
bb16:
|
||||
br label %bb10
|
||||
|
||||
bb17:
|
||||
br label %bb18
|
||||
|
||||
bb18:
|
||||
br i1 undef, label %bb22, label %bb13
|
||||
|
||||
bb19:
|
||||
br i1 undef, label %bb20, label %bb21
|
||||
|
||||
bb20:
|
||||
unreachable
|
||||
|
||||
bb21:
|
||||
br label %bb18
|
||||
|
||||
bb22:
|
||||
br label %bb23
|
||||
|
||||
bb23:
|
||||
br i1 undef, label %bb24, label %bb13
|
||||
|
||||
bb24:
|
||||
br i1 undef, label %bb26, label %bb25
|
||||
|
||||
bb25:
|
||||
br label %bb19
|
||||
|
||||
bb26:
|
||||
br label %bb1
|
||||
|
||||
bb27:
|
||||
br label %bb24
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
; RUN: opt -jump-threading -disable-output < %s
|
||||
; PR9112
|
||||
|
||||
; This is actually a test for value tracking. Jump threading produces
|
||||
; "%phi = phi i16" when it removes all edges leading to %unreachable.
|
||||
; The .ll parser won't let us write that directly since it's invalid code.
|
||||
|
||||
define void @func() nounwind {
|
||||
entry:
|
||||
br label %bb
|
||||
|
||||
bb:
|
||||
br label %bb
|
||||
|
||||
unreachable:
|
||||
%phi = phi i16 [ %add, %unreachable ], [ 0, %next ]
|
||||
%add = add i16 0, %phi
|
||||
%cmp = icmp slt i16 %phi, 0
|
||||
br i1 %cmp, label %unreachable, label %next
|
||||
|
||||
next:
|
||||
br label %unreachable
|
||||
}
|
||||
|
@ -1,246 +0,0 @@
|
||||
; RUN: opt -jump-threading -S -verify < %s | FileCheck %s
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
declare void @f3()
|
||||
declare void @f4(i32)
|
||||
|
||||
|
||||
; Make sure we update the phi node properly.
|
||||
;
|
||||
; CHECK-LABEL: define void @test_br_folding_not_threading_update_phi(
|
||||
; CHECK: br label %L1
|
||||
; Make sure we update the phi node properly here, i.e. we only have 2 predecessors, entry and L0
|
||||
; CHECK: %res.0 = phi i32 [ 0, %L0 ], [ 1, %entry ]
|
||||
define void @test_br_folding_not_threading_update_phi(i32 %val) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %val, 32
|
||||
br i1 %cmp, label %L0, label %L1
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
switch i32 %val, label %L2 [
|
||||
i32 0, label %L1
|
||||
i32 32, label %L1
|
||||
]
|
||||
|
||||
L1:
|
||||
%res.0 = phi i32 [ 0, %L0 ], [ 0, %L0 ], [1, %entry]
|
||||
call void @f4(i32 %res.0)
|
||||
ret void
|
||||
L2:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can fold this branch ... We will not be able to thread it as
|
||||
; L0 is too big to duplicate. L2 is the unreachable block here.
|
||||
;
|
||||
; CHECK-LABEL: @test_br_folding_not_threading(
|
||||
; CHECK: L1:
|
||||
; CHECK: call i32 @f2()
|
||||
; CHECK: call void @f3()
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NOT: br
|
||||
; CHECK: L3:
|
||||
define void @test_br_folding_not_threading(i1 %cond) nounwind {
|
||||
entry:
|
||||
br i1 %cond, label %L0, label %L3
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
br i1 %cond, label %L1, label %L2
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f3()
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; Make sure we can fold this branch ... We will not be able to thread it as
|
||||
; L0 is too big to duplicate. L2 is the unreachable block here.
|
||||
; With more than 1 predecessors.
|
||||
;
|
||||
; CHECK-LABEL: @test_br_folding_not_threading_multiple_preds(
|
||||
; CHECK: L1:
|
||||
; CHECK: call i32 @f2()
|
||||
; CHECK: call void @f3()
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NOT: br
|
||||
; CHECK: L3:
|
||||
define void @test_br_folding_not_threading_multiple_preds(i1 %condx, i1 %cond) nounwind {
|
||||
entry:
|
||||
br i1 %condx, label %X0, label %X1
|
||||
|
||||
X0:
|
||||
br i1 %cond, label %L0, label %L3
|
||||
|
||||
X1:
|
||||
br i1 %cond, label %L0, label %L3
|
||||
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
br i1 %cond, label %L1, label %L2
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f3()
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can do the RAUW for %add...
|
||||
;
|
||||
; CHECK-LABEL: @rauw_if_possible(
|
||||
; CHECK: call void @f4(i32 96)
|
||||
define void @rauw_if_possible(i32 %value) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %value, 32
|
||||
br i1 %cmp, label %L0, label %L3
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
%add = add i32 %value, 64
|
||||
switch i32 %add, label %L3 [
|
||||
i32 32, label %L1
|
||||
i32 96, label %L2
|
||||
]
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f4(i32 %add)
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can NOT do the RAUW for %add...
|
||||
;
|
||||
; CHECK-LABEL: @rauw_if_possible2(
|
||||
; CHECK: call void @f4(i32 %add)
|
||||
define void @rauw_if_possible2(i32 %value) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %value, 32
|
||||
%add = add i32 %value, 64
|
||||
br i1 %cmp, label %L0, label %L2
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
switch i32 %add, label %L3 [
|
||||
i32 32, label %L1
|
||||
i32 96, label %L2
|
||||
]
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
L2:
|
||||
call void @f4(i32 %add)
|
||||
ret void
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure we can fold this branch ... We will not be able to thread it as
|
||||
; L0 is too big to duplicate.
|
||||
; We do not attempt to rewrite the indirectbr target here, but we still take
|
||||
; its target after L0 into account and that enables us to fold.
|
||||
;
|
||||
; L2 is the unreachable block here.
|
||||
;
|
||||
; CHECK-LABEL: @test_br_folding_not_threading_indirect_branch(
|
||||
; CHECK: L1:
|
||||
; CHECK: call i32 @f2()
|
||||
; CHECK: call void @f3()
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NOT: br
|
||||
; CHECK: L3:
|
||||
define void @test_br_folding_not_threading_indirect_branch(i1 %condx, i1 %cond) nounwind {
|
||||
entry:
|
||||
br i1 %condx, label %X0, label %X1
|
||||
|
||||
X0:
|
||||
br i1 %cond, label %L0, label %L3
|
||||
|
||||
X1:
|
||||
br i1 %cond, label %XX1, label %L3
|
||||
|
||||
XX1:
|
||||
indirectbr i8* blockaddress(@test_br_folding_not_threading_indirect_branch, %L0), [label %L0]
|
||||
|
||||
L0:
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
call i32 @f2()
|
||||
br i1 %cond, label %L1, label %L2
|
||||
|
||||
L1:
|
||||
call void @f3()
|
||||
ret void
|
||||
|
||||
L2:
|
||||
call void @f3()
|
||||
ret void
|
||||
|
||||
L3:
|
||||
call void @f3()
|
||||
ret void
|
||||
}
|
@ -1,383 +0,0 @@
|
||||
; RUN: opt < %s -jump-threading -dce -S | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
declare i32 @f1()
|
||||
declare i32 @f2()
|
||||
|
||||
define i32 @branch_implies_guard(i32 %a) {
|
||||
; CHECK-LABEL: @branch_implies_guard(
|
||||
%cond = icmp slt i32 %a, 10
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
; CHECK: T1.split
|
||||
; CHECK: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: %retVal
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
; CHECK: F1.split
|
||||
; CHECK: %v2 = call i32 @f2()
|
||||
; CHECK-NEXT: %retVal
|
||||
; CHECK-NEXT: %condGuard
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %condGuard
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge
|
||||
; CHECK-NOT: call void(i1, ...) @llvm.experimental.guard(
|
||||
%retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
|
||||
%retVal = add i32 %retPhi, 10
|
||||
%condGuard = icmp slt i32 %a, 20
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
ret i32 %retVal
|
||||
}
|
||||
|
||||
define i32 @not_branch_implies_guard(i32 %a) {
|
||||
; CHECK-LABEL: @not_branch_implies_guard(
|
||||
%cond = icmp slt i32 %a, 20
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
; CHECK: T1.split:
|
||||
; CHECK-NEXT: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: %retVal
|
||||
; CHECK-NEXT: %condGuard
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %condGuard
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
; CHECK: F1.split:
|
||||
; CHECK-NEXT: %v2 = call i32 @f2()
|
||||
; CHECK-NEXT: %retVal
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge
|
||||
; CHECK-NOT: call void(i1, ...) @llvm.experimental.guard(
|
||||
%retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
|
||||
%retVal = add i32 %retPhi, 10
|
||||
%condGuard = icmp sgt i32 %a, 10
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
ret i32 %retVal
|
||||
}
|
||||
|
||||
define i32 @branch_overlaps_guard(i32 %a) {
|
||||
; CHECK-LABEL: @branch_overlaps_guard(
|
||||
%cond = icmp slt i32 %a, 20
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
; CHECK: T1:
|
||||
; CHECK-NEXT: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
; CHECK: F1:
|
||||
; CHECK-NEXT: %v2 = call i32 @f2()
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge
|
||||
; CHECK: %condGuard = icmp slt i32 %a, 10
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
%retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
|
||||
%retVal = add i32 %retPhi, 10
|
||||
%condGuard = icmp slt i32 %a, 10
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
ret i32 %retVal
|
||||
}
|
||||
|
||||
define i32 @branch_doesnt_overlap_guard(i32 %a) {
|
||||
; CHECK-LABEL: @branch_doesnt_overlap_guard(
|
||||
%cond = icmp slt i32 %a, 10
|
||||
br i1 %cond, label %T1, label %F1
|
||||
|
||||
T1:
|
||||
; CHECK: T1:
|
||||
; CHECK-NEXT: %v1 = call i32 @f1()
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v1 = call i32 @f1()
|
||||
br label %Merge
|
||||
|
||||
F1:
|
||||
; CHECK: F1:
|
||||
; CHECK-NEXT: %v2 = call i32 @f2()
|
||||
; CHECK-NEXT: br label %Merge
|
||||
%v2 = call i32 @f2()
|
||||
br label %Merge
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge
|
||||
; CHECK: %condGuard = icmp sgt i32 %a, 20
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
%retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
|
||||
%retVal = add i32 %retPhi, 10
|
||||
%condGuard = icmp sgt i32 %a, 20
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
|
||||
ret i32 %retVal
|
||||
}
|
||||
|
||||
define i32 @not_a_diamond1(i32 %a, i1 %cond1) {
|
||||
; CHECK-LABEL: @not_a_diamond1(
|
||||
br i1 %cond1, label %Pred, label %Exit
|
||||
|
||||
Pred:
|
||||
; CHECK: Pred:
|
||||
; CHECK-NEXT: switch i32 %a, label %Exit
|
||||
switch i32 %a, label %Exit [
|
||||
i32 10, label %Merge
|
||||
i32 20, label %Merge
|
||||
]
|
||||
|
||||
Merge:
|
||||
; CHECK: Merge:
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||
; CHECK-NEXT: br label %Exit
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||
br label %Exit
|
||||
|
||||
Exit:
|
||||
; CHECK: Exit:
|
||||
; CHECK-NEXT: ret i32 %a
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define void @not_a_diamond2(i32 %a, i1 %cond1) {
|
||||
; CHECK-LABEL: @not_a_diamond2(
|
||||
br label %Parent
|
||||
|
||||
Merge:
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond1)[ "deopt"() ]
|
||||
ret void
|
||||
|
||||
Pred:
|
||||
; CHECK-NEXT: Pred:
|
||||
; CHECK-NEXT: switch i32 %a, label %Exit
|
||||
switch i32 %a, label %Exit [
|
||||
i32 10, label %Merge
|
||||
i32 20, label %Merge
|
||||
]
|
||||
|
||||
Parent:
|
||||
br label %Pred
|
||||
|
||||
Exit:
|
||||
; CHECK: Merge:
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ]
|
||||
; CHECK-NEXT: ret void
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @never_called(i1)
|
||||
|
||||
; LVI uses guard to identify value of %c2 in branch as true, we cannot replace that
|
||||
; guard with guard(true & c1).
|
||||
define void @dont_fold_guard(i8* %addr, i32 %i, i32 %length) {
|
||||
; CHECK-LABEL: dont_fold_guard
|
||||
; CHECK: %wide.chk = and i1 %c1, %c2
|
||||
; CHECK-NEXT: experimental.guard(i1 %wide.chk)
|
||||
; CHECK-NEXT: call void @never_called(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
%c1 = icmp ult i32 %i, %length
|
||||
%c2 = icmp eq i32 %i, 0
|
||||
%wide.chk = and i1 %c1, %c2
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
|
||||
br i1 %c2, label %BB1, label %BB2
|
||||
|
||||
BB1:
|
||||
call void @never_called(i1 %c2)
|
||||
ret void
|
||||
|
||||
BB2:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @dummy(i1) nounwind argmemonly
|
||||
; same as dont_fold_guard1 but there's a use immediately after guard and before
|
||||
; branch. We can fold that use.
|
||||
define void @dont_fold_guard2(i8* %addr, i32 %i, i32 %length) {
|
||||
; CHECK-LABEL: dont_fold_guard2
|
||||
; CHECK: %wide.chk = and i1 %c1, %c2
|
||||
; CHECK-NEXT: experimental.guard(i1 %wide.chk)
|
||||
; CHECK-NEXT: dummy(i1 true)
|
||||
; CHECK-NEXT: call void @never_called(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
%c1 = icmp ult i32 %i, %length
|
||||
%c2 = icmp eq i32 %i, 0
|
||||
%wide.chk = and i1 %c1, %c2
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
|
||||
call void @dummy(i1 %c2)
|
||||
br i1 %c2, label %BB1, label %BB2
|
||||
|
||||
BB1:
|
||||
call void @never_called(i1 %c2)
|
||||
ret void
|
||||
|
||||
BB2:
|
||||
ret void
|
||||
}
|
||||
|
||||
; same as dont_fold_guard1 but condition %cmp is not an instruction.
|
||||
; We cannot fold the guard under any circumstance.
|
||||
; FIXME: We can merge unreachableBB2 into not_zero.
|
||||
define void @dont_fold_guard3(i8* %addr, i1 %cmp, i32 %i, i32 %length) {
|
||||
; CHECK-LABEL: dont_fold_guard3
|
||||
; CHECK: guard(i1 %cmp)
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
br i1 %cmp, label %BB1, label %BB2
|
||||
|
||||
BB1:
|
||||
call void @never_called(i1 %cmp)
|
||||
ret void
|
||||
|
||||
BB2:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @f(i1)
|
||||
; Same as dont_fold_guard1 but use switch instead of branch.
|
||||
; triggers source code `ProcessThreadableEdges`.
|
||||
define void @dont_fold_guard4(i1 %cmp1, i32 %i) nounwind {
|
||||
; CHECK-LABEL: dont_fold_guard4
|
||||
; CHECK-LABEL: L2:
|
||||
; CHECK-NEXT: %cmp = icmp eq i32 %i, 0
|
||||
; CHECK-NEXT: guard(i1 %cmp)
|
||||
; CHECK-NEXT: dummy(i1 true)
|
||||
; CHECK-NEXT: @f(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
entry:
|
||||
br i1 %cmp1, label %L0, label %L3
|
||||
L0:
|
||||
%cmp = icmp eq i32 %i, 0
|
||||
call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
|
||||
call void @dummy(i1 %cmp)
|
||||
switch i1 %cmp, label %L3 [
|
||||
i1 false, label %L1
|
||||
i1 true, label %L2
|
||||
]
|
||||
|
||||
L1:
|
||||
ret void
|
||||
L2:
|
||||
call void @f(i1 %cmp)
|
||||
ret void
|
||||
L3:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure that we don't PRE a non-speculable load across a guard.
|
||||
define void @unsafe_pre_across_guard(i8* %p, i1 %load.is.valid) {
|
||||
|
||||
; CHECK-LABEL: @unsafe_pre_across_guard(
|
||||
; CHECK-NOT: loaded.pr
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %load.is.valid) [ "deopt"() ]
|
||||
; CHECK-NEXT: %loaded = load i8, i8* %p
|
||||
; CHECK-NEXT: %continue = icmp eq i8 %loaded, 0
|
||||
; CHECK-NEXT: br i1 %continue, label %exit, label %loop
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %load.is.valid) [ "deopt"() ]
|
||||
%loaded = load i8, i8* %p
|
||||
%continue = icmp eq i8 %loaded, 0
|
||||
br i1 %continue, label %exit, label %loop
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure that we can safely PRE a speculable load across a guard.
|
||||
define void @safe_pre_across_guard(i8* noalias nocapture readonly dereferenceable(8) %p, i1 %load.is.valid) {
|
||||
|
||||
; CHECK-LABEL: @safe_pre_across_guard(
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: %loaded.pr = load i8, i8* %p
|
||||
; CHECK-NEXT: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: %loaded = phi i8 [ %loaded, %loop ], [ %loaded.pr, %entry ]
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %load.is.valid) [ "deopt"() ]
|
||||
; CHECK-NEXT: %continue = icmp eq i8 %loaded, 0
|
||||
; CHECK-NEXT: br i1 %continue, label %exit, label %loop
|
||||
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %load.is.valid) [ "deopt"() ]
|
||||
%loaded = load i8, i8* %p
|
||||
%continue = icmp eq i8 %loaded, 0
|
||||
br i1 %continue, label %exit, label %loop
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure that we don't PRE a non-speculable load across a call which may
|
||||
; alias with the load.
|
||||
define void @unsafe_pre_across_call(i8* %p) {
|
||||
|
||||
; CHECK-LABEL: @unsafe_pre_across_call(
|
||||
; CHECK-NOT: loaded.pr
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: call i32 @f1()
|
||||
; CHECK-NEXT: %loaded = load i8, i8* %p
|
||||
; CHECK-NEXT: %continue = icmp eq i8 %loaded, 0
|
||||
; CHECK-NEXT: br i1 %continue, label %exit, label %loop
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
call i32 @f1()
|
||||
%loaded = load i8, i8* %p
|
||||
%continue = icmp eq i8 %loaded, 0
|
||||
br i1 %continue, label %exit, label %loop
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret void
|
||||
}
|
||||
|
||||
; Make sure that we can safely PRE a speculable load across a call.
|
||||
define void @safe_pre_across_call(i8* noalias nocapture readonly dereferenceable(8) %p) {
|
||||
|
||||
; CHECK-LABEL: @safe_pre_across_call(
|
||||
; CHECK: entry:
|
||||
; CHECK-NEXT: %loaded.pr = load i8, i8* %p
|
||||
; CHECK-NEXT: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: %loaded = phi i8 [ %loaded, %loop ], [ %loaded.pr, %entry ]
|
||||
; CHECK-NEXT: call i32 @f1()
|
||||
; CHECK-NEXT: %continue = icmp eq i8 %loaded, 0
|
||||
; CHECK-NEXT: br i1 %continue, label %exit, label %loop
|
||||
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
call i32 @f1()
|
||||
%loaded = load i8, i8* %p
|
||||
%continue = icmp eq i8 %loaded, 0
|
||||
br i1 %continue, label %exit, label %loop
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret void
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
; RUN: opt -jump-threading -S < %s | FileCheck %s
|
||||
|
||||
declare void @side_effect(i32)
|
||||
|
||||
define void @test0(i32 %i, i32 %len) {
|
||||
; CHECK-LABEL: @test0(
|
||||
entry:
|
||||
call void @side_effect(i32 0)
|
||||
%i.inc = add nuw i32 %i, 1
|
||||
%c0 = icmp ult i32 %i.inc, %len
|
||||
br i1 %c0, label %left, label %right
|
||||
|
||||
left:
|
||||
; CHECK: entry:
|
||||
; CHECK: br i1 %c0, label %left0, label %right
|
||||
|
||||
; CHECK: left0:
|
||||
; CHECK: call void @side_effect
|
||||
; CHECK-NOT: br i1 %c1
|
||||
; CHECK: call void @side_effect
|
||||
call void @side_effect(i32 0)
|
||||
%c1 = icmp ult i32 %i, %len
|
||||
br i1 %c1, label %left0, label %right
|
||||
|
||||
left0:
|
||||
call void @side_effect(i32 0)
|
||||
ret void
|
||||
|
||||
right:
|
||||
%t = phi i32 [ 1, %left ], [ 2, %entry ]
|
||||
call void @side_effect(i32 %t)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test1(i32 %i, i32 %len) {
|
||||
; CHECK-LABEL: @test1(
|
||||
entry:
|
||||
call void @side_effect(i32 0)
|
||||
%i.inc = add nsw i32 %i, 1
|
||||
%c0 = icmp slt i32 %i.inc, %len
|
||||
br i1 %c0, label %left, label %right
|
||||
|
||||
left:
|
||||
; CHECK: entry:
|
||||
; CHECK: br i1 %c0, label %left0, label %right
|
||||
|
||||
; CHECK: left0:
|
||||
; CHECK: call void @side_effect
|
||||
; CHECK-NOT: br i1 %c1
|
||||
; CHECK: call void @side_effect
|
||||
call void @side_effect(i32 0)
|
||||
%c1 = icmp slt i32 %i, %len
|
||||
br i1 %c1, label %left0, label %right
|
||||
|
||||
left0:
|
||||
call void @side_effect(i32 0)
|
||||
ret void
|
||||
|
||||
right:
|
||||
%t = phi i32 [ 1, %left ], [ 2, %entry ]
|
||||
call void @side_effect(i32 %t)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test2(i32 %i, i32 %len, i1* %c.ptr) {
|
||||
; CHECK-LABEL: @test2(
|
||||
|
||||
; CHECK: entry:
|
||||
; CHECK: br i1 %c0, label %cont, label %right
|
||||
; CHECK: cont:
|
||||
; CHECK: br i1 %c, label %left0, label %right
|
||||
; CHECK: left0:
|
||||
; CHECK: call void @side_effect(i32 0)
|
||||
; CHECK: call void @side_effect(i32 0)
|
||||
entry:
|
||||
call void @side_effect(i32 0)
|
||||
%i.inc = add nsw i32 %i, 1
|
||||
%c0 = icmp slt i32 %i.inc, %len
|
||||
br i1 %c0, label %cont, label %right
|
||||
|
||||
cont:
|
||||
%c = load i1, i1* %c.ptr
|
||||
br i1 %c, label %left, label %right
|
||||
|
||||
left:
|
||||
call void @side_effect(i32 0)
|
||||
%c1 = icmp slt i32 %i, %len
|
||||
br i1 %c1, label %left0, label %right
|
||||
|
||||
left0:
|
||||
call void @side_effect(i32 0)
|
||||
ret void
|
||||
|
||||
right:
|
||||
%t = phi i32 [ 1, %left ], [ 2, %entry ], [ 3, %cont ]
|
||||
call void @side_effect(i32 %t)
|
||||
ret void
|
||||
}
|
||||
|
||||
; A s<= B implies A s> B is false.
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK: entry:
|
||||
; CHECK: br i1 %cmp, label %if.end, label %if.end3
|
||||
; CHECK-NOT: br i1 %cmp1, label %if.then2, label %if.end
|
||||
; CHECK-NOT: call void @side_effect(i32 0)
|
||||
; CHECK: br label %if.end3
|
||||
; CHECK: ret void
|
||||
|
||||
define void @test3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%cmp = icmp sle i32 %a, %b
|
||||
br i1 %cmp, label %if.then, label %if.end3
|
||||
|
||||
if.then:
|
||||
%cmp1 = icmp sgt i32 %a, %b
|
||||
br i1 %cmp1, label %if.then2, label %if.end
|
||||
|
||||
if.then2:
|
||||
call void @side_effect(i32 0)
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
br label %if.end3
|
||||
|
||||
if.end3:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @is(i1)
|
||||
|
||||
; If A >=s B is false then A <=s B is implied true.
|
||||
; CHECK-LABEL: @test_sge_sle
|
||||
; CHECK: call void @is(i1 true)
|
||||
; CHECK-NOT: call void @is(i1 false)
|
||||
define void @test_sge_sle(i32 %a, i32 %b) {
|
||||
%cmp1 = icmp sge i32 %a, %b
|
||||
br i1 %cmp1, label %untaken, label %taken
|
||||
|
||||
taken:
|
||||
%cmp2 = icmp sle i32 %a, %b
|
||||
br i1 %cmp2, label %istrue, label %isfalse
|
||||
|
||||
istrue:
|
||||
call void @is(i1 true)
|
||||
ret void
|
||||
|
||||
isfalse:
|
||||
call void @is(i1 false)
|
||||
ret void
|
||||
|
||||
untaken:
|
||||
ret void
|
||||
}
|
||||
|
||||
; If A <=s B is false then A <=s B is implied false.
|
||||
; CHECK-LABEL: @test_sle_sle
|
||||
; CHECK-NOT: call void @is(i1 true)
|
||||
; CHECK: call void @is(i1 false)
|
||||
define void @test_sle_sle(i32 %a, i32 %b) {
|
||||
%cmp1 = icmp sle i32 %a, %b
|
||||
br i1 %cmp1, label %untaken, label %taken
|
||||
|
||||
taken:
|
||||
%cmp2 = icmp sle i32 %a, %b
|
||||
br i1 %cmp2, label %istrue, label %isfalse
|
||||
|
||||
istrue:
|
||||
call void @is(i1 true)
|
||||
ret void
|
||||
|
||||
isfalse:
|
||||
call void @is(i1 false)
|
||||
ret void
|
||||
|
||||
untaken:
|
||||
ret void
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user