mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[SCCP] Add a few constantexpr,undef tests for cond propagation
This commit is contained in:
parent
6526abbd2a
commit
e5992f6a74
272
test/Transforms/SCCP/conditions-ranges-with-undef.ll
Normal file
272
test/Transforms/SCCP/conditions-ranges-with-undef.ll
Normal file
@ -0,0 +1,272 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -ipsccp -S | FileCheck %s
|
||||
|
||||
declare void @use(i1)
|
||||
|
||||
; We can simplify the conditions in the true block, because the condition
|
||||
; allows us to replace all uses of %a in the block with a constant.
|
||||
define void @val_undef_eq() {
|
||||
; CHECK-LABEL: @val_undef_eq(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A:%.*]] = add i32 undef, 0
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[A]], 10
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: call void @use(i1 false)
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a = add i32 undef, 0
|
||||
%bc.1 = icmp eq i32 %a, 10
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp ne i32 %a, 10
|
||||
call void @use(i1 %f.1)
|
||||
%f.2 = icmp eq i32 %a, 10
|
||||
call void @use(i1 %f.2)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @use.i32(i32)
|
||||
|
||||
; It is not allowed to use the range information from the condition to remove
|
||||
; %a.127 = and ... in the true block, as %a could be undef.
|
||||
define void @val_undef_range() {
|
||||
; CHECK-LABEL: @val_undef_range(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A:%.*]] = add i32 undef, 0
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[A]], 127
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 128
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
|
||||
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a = add i32 undef, 0
|
||||
%bc.1 = icmp ult i32 %a, 127
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp eq i32 %a, 128
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%a.127 = and i32 %a, 127
|
||||
call void @use.i32(i32 %a.127)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
; All uses of %p can be replaced by a constant (10).
|
||||
define void @val_singlecrfromundef_range(i1 %cond) {
|
||||
; CHECK-LABEL: @val_singlecrfromundef_range(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
|
||||
; CHECK: inc1:
|
||||
; CHECK-NEXT: br label [[IF:%.*]]
|
||||
; CHECK: inc2:
|
||||
; CHECK-NEXT: br label [[IF]]
|
||||
; CHECK: if:
|
||||
; CHECK-NEXT: br label [[TRUE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: call void @use(i1 false)
|
||||
; CHECK-NEXT: call void @use.i32(i32 10)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
|
||||
br i1 %cond, label %inc1, label %inc2
|
||||
|
||||
inc1:
|
||||
br label %if
|
||||
|
||||
inc2:
|
||||
br label %if
|
||||
|
||||
if:
|
||||
%p = phi i32 [ 10, %inc1 ], [ undef, %inc2 ]
|
||||
%bc.1 = icmp ult i32 %p, 127
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp eq i32 %p, 128
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%p.127 = and i32 %p, 127
|
||||
call void @use.i32(i32 %p.127)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; It is not allowed to use the information from the condition ([0, 128))
|
||||
; to remove a.127.2 = and i32 %p, 127, as %p might be undef.
|
||||
define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) {
|
||||
; CHECK-LABEL: @val_undef_to_cr_to_overdef_range(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A:%.*]], 127
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[INC1:%.*]], label [[INC2:%.*]]
|
||||
; CHECK: inc1:
|
||||
; CHECK-NEXT: br label [[IF:%.*]]
|
||||
; CHECK: inc2:
|
||||
; CHECK-NEXT: br label [[IF]]
|
||||
; CHECK: if:
|
||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A_127]], [[INC1]] ], [ undef, [[INC2]] ]
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp ult i32 [[P]], 100
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[P]], 128
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[P_127:%.*]] = and i32 [[P]], 127
|
||||
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a.127 = and i32 %a, 127
|
||||
br i1 %cond, label %inc1, label %inc2
|
||||
|
||||
inc1:
|
||||
br label %if
|
||||
|
||||
inc2:
|
||||
br label %if
|
||||
|
||||
if:
|
||||
%p = phi i32 [ %a.127, %inc1 ], [ undef, %inc2 ]
|
||||
%bc.1 = icmp ult i32 %p, 100
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp eq i32 %p, 128
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%p.127 = and i32 %p, 127
|
||||
call void @use.i32(i32 %p.127)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
; All uses of %p can be replaced by a constant (10), we are allowed to use it
|
||||
; as a bound too.
|
||||
define void @bound_singlecrfromundef(i32 %a, i1 %cond) {
|
||||
; CHECK-LABEL: @bound_singlecrfromundef(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: br label [[PRED:%.*]]
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: br label [[PRED]]
|
||||
; CHECK: pred:
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A:%.*]], 10
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 5
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[A]], 5
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
|
||||
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
br label %pred
|
||||
|
||||
bb2:
|
||||
br label %pred
|
||||
|
||||
pred:
|
||||
%p = phi i32 [ undef, %bb1 ], [ 10, %bb2 ]
|
||||
%bc.1 = icmp ugt i32 %a, %p
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp eq i32 %a, 5
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%t.1 = icmp ne i32 %a, 5
|
||||
call void @use(i1 %t.1)
|
||||
|
||||
%a.127 = and i32 %a, 127
|
||||
call void @use.i32(i32 %a.127)
|
||||
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
; It is not allowed to use the information from %p as a bound, because an
|
||||
; incoming value is undef.
|
||||
define void @bound_range_and_undef(i32 %a, i1 %cond) {
|
||||
; CHECK-LABEL: @bound_range_and_undef(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A_10:%.*]] = and i32 [[A:%.*]], 127
|
||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: br label [[PRED:%.*]]
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: br label [[PRED]]
|
||||
; CHECK: pred:
|
||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A_10]], [[BB1]] ], [ undef, [[BB2]] ]
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp ugt i32 [[A]], [[P]]
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 300
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[A_127_2:%.*]] = and i32 [[P]], 127
|
||||
; CHECK-NEXT: call void @use.i32(i32 [[A_127_2]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a.10 = and i32 %a, 127
|
||||
br i1 %cond, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
br label %pred
|
||||
|
||||
bb2:
|
||||
br label %pred
|
||||
|
||||
pred:
|
||||
%p = phi i32 [ %a.10, %bb1 ], [ undef, %bb2 ]
|
||||
%bc.1 = icmp ugt i32 %a, %p
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true:
|
||||
%f.1 = icmp eq i32 %a, 300
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%a.127.2 = and i32 %p, 127
|
||||
call void @use.i32(i32 %a.127.2)
|
||||
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
@ -232,136 +232,6 @@ false:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @loop.1() {
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.cond.cleanup13, %if.then
|
||||
%i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ]
|
||||
%cmp9 = icmp sle i32 %i.0, 3
|
||||
br i1 %cmp9, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.cond
|
||||
ret void
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
br label %for.cond11
|
||||
|
||||
for.cond11: ; preds = %arrayctor.cont21, %for.body
|
||||
br label %for.cond.cleanup13
|
||||
|
||||
for.cond.cleanup13: ; preds = %for.cond11
|
||||
%inc27 = add nsw i32 %i.0, 1
|
||||
br label %for.cond
|
||||
}
|
||||
|
||||
|
||||
define void @loop() {
|
||||
; CHECK-LABEL: @loop(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
; CHECK: for.cond:
|
||||
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC27:%.*]], [[FOR_COND_CLEANUP13:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP9:%.*]] = icmp sle i32 [[I_0]], 3
|
||||
; CHECK-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
||||
; CHECK: for.cond.cleanup:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: br label [[FOR_COND11:%.*]]
|
||||
; CHECK: for.cond11:
|
||||
; CHECK-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[FOR_BODY]] ], [ [[INC:%.*]], [[FOR_BODY14:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP12:%.*]] = icmp slt i32 [[J_0]], 2
|
||||
; CHECK-NEXT: br i1 [[CMP12]], label [[FOR_BODY14]], label [[FOR_COND_CLEANUP13]]
|
||||
; CHECK: for.cond.cleanup13:
|
||||
; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1
|
||||
; CHECK-NEXT: br label [[FOR_COND]]
|
||||
; CHECK: for.body14:
|
||||
; CHECK-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
|
||||
; CHECK-NEXT: br label [[FOR_COND11]]
|
||||
;
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.cond.cleanup13, %if.then
|
||||
%i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ]
|
||||
%cmp9 = icmp sle i32 %i.0, 3
|
||||
br i1 %cmp9, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.cond
|
||||
ret void
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
br label %for.cond11
|
||||
|
||||
for.cond11: ; preds = %arrayctor.cont21, %for.body
|
||||
%j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.body14 ]
|
||||
%cmp12 = icmp slt i32 %j.0, 2
|
||||
br i1 %cmp12, label %for.body14, label %for.cond.cleanup13
|
||||
|
||||
for.cond.cleanup13: ; preds = %for.cond11
|
||||
%inc27 = add nsw i32 %i.0, 1
|
||||
br label %for.cond
|
||||
|
||||
for.body14:
|
||||
%inc = add nsw i32 %j.0, 1
|
||||
br label %for.cond11
|
||||
}
|
||||
|
||||
define i32 @udiv_1(i64 %sz) {
|
||||
; CHECK-LABEL: @udiv_1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 4088, [[SZ:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||
; CHECK: cond.true:
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]]
|
||||
; CHECK-NEXT: br label [[COND_END]]
|
||||
; CHECK: cond.end:
|
||||
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
entry:
|
||||
%cmp = icmp ugt i64 4088, %sz
|
||||
br i1 %cmp, label %cond.true, label %cond.end
|
||||
|
||||
cond.true: ; preds = %entry
|
||||
%div = udiv i64 4088, %sz
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %entry, %cond.true
|
||||
%cond = phi i64 [ %div, %cond.true ], [ 1, %entry ]
|
||||
%conv = trunc i64 %cond to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
; Same as @udiv_1, but with the condition switched.
|
||||
define i32 @udiv_2(i64 %sz) {
|
||||
; CHECK-LABEL: @udiv_2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[SZ:%.*]], 4088
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||
; CHECK: cond.true:
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]]
|
||||
; CHECK-NEXT: br label [[COND_END]]
|
||||
; CHECK: cond.end:
|
||||
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %sz, 4088
|
||||
br i1 %cmp, label %cond.true, label %cond.end
|
||||
|
||||
cond.true: ; preds = %entry
|
||||
%div = udiv i64 4088, %sz
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %entry, %cond.true
|
||||
%cond = phi i64 [ %div, %cond.true ], [ 1, %entry ]
|
||||
%conv = trunc i64 %cond to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
; Test with 2 unrelated nested conditions.
|
||||
define void @f7_nested_conds(i32* %a, i32 %b) {
|
||||
; CHECK-LABEL: @f7_nested_conds(
|
||||
@ -710,3 +580,273 @@ true: ; %b in [0, 256)
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f11_contradiction(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @f11_contradiction(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 [[B:%.*]], 10
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: br label [[FALSE]]
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%bc.1 = icmp eq i32 %b, 10
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true: ; %b in [10, 11)
|
||||
%bc.2 = icmp eq i32 %b, 20
|
||||
br i1 %bc.2, label %true.2, label %false
|
||||
|
||||
true.2:
|
||||
%f.1 = icmp eq i32 %b, 256
|
||||
call void @use(i1 %f.1)
|
||||
%f.2 = icmp ne i32 %b, 300
|
||||
call void @use(i1 %f.2)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f12_float(float %b) {
|
||||
; CHECK-LABEL: @f12_float(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = fcmp olt float 1.000000e+00, [[B:%.*]]
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: call void @use(i1 false)
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a = fadd float 0.0, 1.0
|
||||
%bc.1 = fcmp olt float %a, %b
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true: ; %b in [10, 11)
|
||||
%f.1 = fcmp one float %a, 1.0
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%t.1 = fcmp oeq float %a, 1.0
|
||||
call void @use(i1 %t.1)
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
@A = global i32 17
|
||||
@B = global i32 17
|
||||
|
||||
define void @f13_constexpr1() {
|
||||
; CHECK-LABEL: @f13_constexpr1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[BC_1:%.*]] = icmp eq i32 add (i32 ptrtoint (i32* @A to i32), i32 10), 55
|
||||
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 add (i32 ptrtoint (i32* @A to i32), i32 10), 10
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[F_2:%.*]] = icmp eq i32 add (i32 ptrtoint (i32* @A to i32), i32 10), 55
|
||||
; CHECK-NEXT: call void @use(i1 [[F_2]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a = add i32 ptrtoint (i32* @A to i32), 10
|
||||
%bc.1 = icmp eq i32 %a, 55
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true: ; %b in [10, 11)
|
||||
%f.1 = icmp eq i32 %a, 10
|
||||
call void @use(i1 %f.1)
|
||||
%f.2 = icmp eq i32 %a, 55
|
||||
call void @use(i1 %f.2)
|
||||
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
; TODO: can we fold the compares in the true block?
|
||||
define void @f14_constexpr2() {
|
||||
; CHECK-LABEL: @f14_constexpr2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 icmp eq (i32 ptrtoint (i32* @A to i32), i32 ptrtoint (i32* @B to i32)), label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: call void @use(i1 icmp ne (i32 ptrtoint (i32* @A to i32), i32 ptrtoint (i32* @B to i32)))
|
||||
; CHECK-NEXT: call void @use(i1 icmp eq (i32 ptrtoint (i32* @A to i32), i32 ptrtoint (i32* @B to i32)))
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%a = add i32 ptrtoint (i32* @A to i32), 0
|
||||
%b = add i32 ptrtoint (i32* @B to i32), 0
|
||||
%bc.1 = icmp eq i32 %a, %b
|
||||
br i1 %bc.1, label %true, label %false
|
||||
|
||||
true: ; %b in [10, 11)
|
||||
%f.1 = icmp ne i32 %a, %b
|
||||
call void @use(i1 %f.1)
|
||||
%f.2 = icmp eq i32 %a, %b
|
||||
call void @use(i1 %f.2)
|
||||
|
||||
ret void
|
||||
|
||||
false:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @loop_1() {
|
||||
; CHECK-LABEL: @loop_1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
; CHECK: for.cond:
|
||||
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC27:%.*]], [[FOR_COND_CLEANUP13:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP9:%.*]] = icmp sle i32 [[I_0]], 3
|
||||
; CHECK-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
||||
; CHECK: for.cond.cleanup:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: br label [[FOR_COND11:%.*]]
|
||||
; CHECK: for.cond11:
|
||||
; CHECK-NEXT: br label [[FOR_COND_CLEANUP13]]
|
||||
; CHECK: for.cond.cleanup13:
|
||||
; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1
|
||||
; CHECK-NEXT: br label [[FOR_COND]]
|
||||
;
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.cond.cleanup13, %if.then
|
||||
%i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ]
|
||||
%cmp9 = icmp sle i32 %i.0, 3
|
||||
br i1 %cmp9, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.cond
|
||||
ret void
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
br label %for.cond11
|
||||
|
||||
for.cond11: ; preds = %arrayctor.cont21, %for.body
|
||||
br label %for.cond.cleanup13
|
||||
|
||||
for.cond.cleanup13: ; preds = %for.cond11
|
||||
%inc27 = add nsw i32 %i.0, 1
|
||||
br label %for.cond
|
||||
}
|
||||
|
||||
|
||||
define void @loop() {
|
||||
; CHECK-LABEL: @loop(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
; CHECK: for.cond:
|
||||
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC27:%.*]], [[FOR_COND_CLEANUP13:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP9:%.*]] = icmp sle i32 [[I_0]], 3
|
||||
; CHECK-NEXT: br i1 [[CMP9]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
||||
; CHECK: for.cond.cleanup:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: br label [[FOR_COND11:%.*]]
|
||||
; CHECK: for.cond11:
|
||||
; CHECK-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[FOR_BODY]] ], [ [[INC:%.*]], [[FOR_BODY14:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP12:%.*]] = icmp slt i32 [[J_0]], 2
|
||||
; CHECK-NEXT: br i1 [[CMP12]], label [[FOR_BODY14]], label [[FOR_COND_CLEANUP13]]
|
||||
; CHECK: for.cond.cleanup13:
|
||||
; CHECK-NEXT: [[INC27]] = add nsw i32 [[I_0]], 1
|
||||
; CHECK-NEXT: br label [[FOR_COND]]
|
||||
; CHECK: for.body14:
|
||||
; CHECK-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
|
||||
; CHECK-NEXT: br label [[FOR_COND11]]
|
||||
;
|
||||
entry:
|
||||
br label %for.cond
|
||||
|
||||
for.cond: ; preds = %for.cond.cleanup13, %if.then
|
||||
%i.0 = phi i32 [ 0, %entry ], [ %inc27, %for.cond.cleanup13 ]
|
||||
%cmp9 = icmp sle i32 %i.0, 3
|
||||
br i1 %cmp9, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.cond
|
||||
ret void
|
||||
|
||||
for.body: ; preds = %for.cond
|
||||
br label %for.cond11
|
||||
|
||||
for.cond11: ; preds = %arrayctor.cont21, %for.body
|
||||
%j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.body14 ]
|
||||
%cmp12 = icmp slt i32 %j.0, 2
|
||||
br i1 %cmp12, label %for.body14, label %for.cond.cleanup13
|
||||
|
||||
for.cond.cleanup13: ; preds = %for.cond11
|
||||
%inc27 = add nsw i32 %i.0, 1
|
||||
br label %for.cond
|
||||
|
||||
for.body14:
|
||||
%inc = add nsw i32 %j.0, 1
|
||||
br label %for.cond11
|
||||
}
|
||||
|
||||
define i32 @udiv_1(i64 %sz) {
|
||||
; CHECK-LABEL: @udiv_1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 4088, [[SZ:%.*]]
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||
; CHECK: cond.true:
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]]
|
||||
; CHECK-NEXT: br label [[COND_END]]
|
||||
; CHECK: cond.end:
|
||||
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
entry:
|
||||
%cmp = icmp ugt i64 4088, %sz
|
||||
br i1 %cmp, label %cond.true, label %cond.end
|
||||
|
||||
cond.true: ; preds = %entry
|
||||
%div = udiv i64 4088, %sz
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %entry, %cond.true
|
||||
%cond = phi i64 [ %div, %cond.true ], [ 1, %entry ]
|
||||
%conv = trunc i64 %cond to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
; Same as @udiv_1, but with the condition switched.
|
||||
define i32 @udiv_2(i64 %sz) {
|
||||
; CHECK-LABEL: @udiv_2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[SZ:%.*]], 4088
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||
; CHECK: cond.true:
|
||||
; CHECK-NEXT: [[DIV:%.*]] = udiv i64 4088, [[SZ]]
|
||||
; CHECK-NEXT: br label [[COND_END]]
|
||||
; CHECK: cond.end:
|
||||
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %sz, 4088
|
||||
br i1 %cmp, label %cond.true, label %cond.end
|
||||
|
||||
cond.true: ; preds = %entry
|
||||
%div = udiv i64 4088, %sz
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %entry, %cond.true
|
||||
%cond = phi i64 [ %div, %cond.true ], [ 1, %entry ]
|
||||
%conv = trunc i64 %cond to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user