The legacy PM is deprecated, so update a bunch of lit tests running opt to use the new PM syntax when specifying the pipeline. In this patch focus has been put on test cases for ConstantMerge, ConstraintElimination, CorrelatedValuePropagation, GlobalDCE, GlobalOpt, SCCP, TailCallElim and PredicateInfo. Differential Revision: https://reviews.llvm.org/D114516
954 lines
36 KiB
LLVM
954 lines
36 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt %s -passes=sccp -S | FileCheck --check-prefix=SCCP %s
|
|
; RUN: opt %s -passes=ipsccp -S | FileCheck --check-prefix=IPSCCP %s
|
|
|
|
; Test different widening scenarios.
|
|
|
|
declare void @use(i1)
|
|
declare i1 @cond()
|
|
|
|
define void @test_2_incoming_constants(i32 %x) {
|
|
; SCCP-LABEL: @test_2_incoming_constants(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: br label [[EXIT]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
|
|
; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: call void @use(i1 true)
|
|
; SCCP-NEXT: call void @use(i1 false)
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @test_2_incoming_constants(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: br label [[EXIT]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
|
|
; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: call void @use(i1 false)
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %bb1, label %exit
|
|
|
|
bb1:
|
|
br label %exit
|
|
|
|
exit:
|
|
%p = phi i32 [0, %entry], [1, %bb1]
|
|
%a = add i32 %p, 1
|
|
%t.1 = icmp ult i32 %a, 20
|
|
call void @use(i1 %t.1)
|
|
%f.1 = icmp ugt i32 %a, 10
|
|
call void @use(i1 %f.1)
|
|
ret void
|
|
}
|
|
|
|
define void @test_3_incoming_constants(i32 %x) {
|
|
; SCCP-LABEL: @test_3_incoming_constants(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
|
|
; SCCP: bb2:
|
|
; SCCP-NEXT: br label [[EXIT]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
|
|
; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: call void @use(i1 true)
|
|
; SCCP-NEXT: call void @use(i1 false)
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @test_3_incoming_constants(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb2:
|
|
; IPSCCP-NEXT: br label [[EXIT]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
|
|
; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: call void @use(i1 false)
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %bb1, label %exit
|
|
|
|
bb1:
|
|
%c.2 = call i1 @cond()
|
|
br i1 %c.2, label %bb2, label %exit
|
|
|
|
bb2:
|
|
br label %exit
|
|
|
|
exit:
|
|
%p = phi i32 [0, %entry], [1, %bb1], [2, %bb2]
|
|
%a = add i32 %p, 1
|
|
%t.1 = icmp ult i32 %a, 20
|
|
call void @use(i1 %t.1)
|
|
%f.1 = icmp ugt i32 %a, 10
|
|
call void @use(i1 %f.1)
|
|
ret void
|
|
}
|
|
|
|
define void @test_5_incoming_constants(i32 %x) {
|
|
; SCCP-LABEL: @test_5_incoming_constants(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
|
|
; SCCP: bb2:
|
|
; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; SCCP: bb3:
|
|
; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
|
|
; SCCP: bb4:
|
|
; SCCP-NEXT: br label [[EXIT]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
|
|
; SCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: call void @use(i1 true)
|
|
; SCCP-NEXT: call void @use(i1 false)
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @test_5_incoming_constants(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb2:
|
|
; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb3:
|
|
; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb4:
|
|
; IPSCCP-NEXT: br label [[EXIT]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
|
|
; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: call void @use(i1 false)
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %bb1, label %exit
|
|
|
|
bb1:
|
|
%c.2 = call i1 @cond()
|
|
br i1 %c.2, label %bb2, label %exit
|
|
|
|
bb2:
|
|
%c.3 = call i1 @cond()
|
|
br i1 %c.3, label %bb3, label %exit
|
|
|
|
bb3:
|
|
%c.4 = call i1 @cond()
|
|
br i1 %c.4, label %bb4, label %exit
|
|
|
|
bb4:
|
|
br label %exit
|
|
|
|
exit:
|
|
%p = phi i32 [0, %entry], [1, %bb1], [2, %bb2], [3, %bb3], [4, %bb4]
|
|
%a = add i32 %p, 1
|
|
%t.1 = icmp ult i32 %a, 20
|
|
call void @use(i1 %t.1)
|
|
%f.1 = icmp ugt i32 %a, 10
|
|
call void @use(i1 %f.1)
|
|
ret void
|
|
}
|
|
|
|
; For the rotated_loop_* test cases %p and %a are extended on each iteration.
|
|
|
|
define void @rotated_loop_2(i32 %x) {
|
|
; SCCP-LABEL: @rotated_loop_2(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
|
|
; SCCP: bb2:
|
|
; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; SCCP: bb3:
|
|
; SCCP-NEXT: br label [[EXIT]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
|
|
; SCCP-NEXT: [[A]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: call void @use(i1 true)
|
|
; SCCP-NEXT: call void @use(i1 false)
|
|
; SCCP-NEXT: br i1 false, label [[EXIT]], label [[EXIT_1:%.*]]
|
|
; SCCP: exit.1:
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @rotated_loop_2(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
|
|
; IPSCCP: bb2:
|
|
; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb3:
|
|
; IPSCCP-NEXT: br label [[EXIT]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
|
|
; IPSCCP-NEXT: [[A:%.*]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: call void @use(i1 false)
|
|
; IPSCCP-NEXT: br label [[EXIT_1:%.*]]
|
|
; IPSCCP: exit.1:
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %exit, label %bb1
|
|
|
|
bb1:
|
|
%c.2 = call i1 @cond()
|
|
br i1 %c.2, label %exit, label %bb2
|
|
|
|
bb2:
|
|
%c.3 = call i1 @cond()
|
|
br i1 %c.3, label %bb3, label %exit
|
|
|
|
bb3:
|
|
br label %exit
|
|
|
|
exit:
|
|
%p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
|
|
%a = add i32 %p, 1
|
|
%t.1 = icmp ult i32 %a, 20
|
|
call void @use(i1 %t.1)
|
|
%f.1 = icmp ugt i32 %a, 10
|
|
call void @use(i1 %f.1)
|
|
%c.4 = icmp ult i32 %a, 2
|
|
br i1 %c.4, label %exit, label %exit.1
|
|
|
|
exit.1:
|
|
ret void
|
|
}
|
|
|
|
define void @rotated_loop_3(i32 %x) {
|
|
; SCCP-LABEL: @rotated_loop_3(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
|
|
; SCCP: bb2:
|
|
; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; SCCP: bb3:
|
|
; SCCP-NEXT: br label [[EXIT]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
|
|
; SCCP-NEXT: [[A]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20
|
|
; SCCP-NEXT: call void @use(i1 [[T_1]])
|
|
; SCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10
|
|
; SCCP-NEXT: call void @use(i1 [[F_1]])
|
|
; SCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3
|
|
; SCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]]
|
|
; SCCP: exit.1:
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @rotated_loop_3(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
|
|
; IPSCCP: bb2:
|
|
; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
|
|
; IPSCCP: bb3:
|
|
; IPSCCP-NEXT: br label [[EXIT]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
|
|
; IPSCCP-NEXT: [[A]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20
|
|
; IPSCCP-NEXT: call void @use(i1 [[T_1]])
|
|
; IPSCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10
|
|
; IPSCCP-NEXT: call void @use(i1 [[F_1]])
|
|
; IPSCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3
|
|
; IPSCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]]
|
|
; IPSCCP: exit.1:
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %exit, label %bb1
|
|
|
|
bb1:
|
|
%c.2 = call i1 @cond()
|
|
br i1 %c.2, label %exit, label %bb2
|
|
|
|
bb2:
|
|
%c.3 = call i1 @cond()
|
|
br i1 %c.3, label %bb3, label %exit
|
|
|
|
bb3:
|
|
br label %exit
|
|
|
|
exit:
|
|
%p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
|
|
%a = add i32 %p, 1
|
|
%t.1 = icmp ult i32 %a, 20
|
|
call void @use(i1 %t.1)
|
|
%f.1 = icmp ugt i32 %a, 10
|
|
call void @use(i1 %f.1)
|
|
%c.4 = icmp ult i32 %a, 3
|
|
br i1 %c.4, label %exit, label %exit.1
|
|
|
|
exit.1:
|
|
ret void
|
|
}
|
|
|
|
; For the loop_with_header_* tests, %iv and %a change on each iteration, but we
|
|
; can use the range imposed by the condition %c.1 when widening.
|
|
define void @loop_with_header_1(i32 %x) {
|
|
; SCCP-LABEL: @loop_with_header_1(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: br label [[LOOP_HEADER:%.*]]
|
|
; SCCP: loop.header:
|
|
; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
|
|
; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
|
|
; SCCP: loop.body:
|
|
; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 2
|
|
; SCCP-NEXT: call void @use(i1 [[T_1]])
|
|
; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
|
|
; SCCP-NEXT: br label [[LOOP_HEADER]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @loop_with_header_1(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]]
|
|
; IPSCCP: loop.header:
|
|
; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
|
|
; IPSCCP: loop.body:
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
|
|
; IPSCCP-NEXT: br label [[LOOP_HEADER]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i32 [0, %entry], [%iv.next, %loop.body]
|
|
%c.1 = icmp slt i32 %iv, 2
|
|
br i1 %c.1, label %loop.body, label %exit
|
|
|
|
loop.body:
|
|
%t.1 = icmp slt i32 %iv, 2
|
|
call void @use(i1 %t.1)
|
|
%iv.next = add nsw i32 %iv, 1
|
|
br label %loop.header
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @loop_with_header_2(i32 %x) {
|
|
; SCCP-LABEL: @loop_with_header_2(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: br label [[LOOP_HEADER:%.*]]
|
|
; SCCP: loop.header:
|
|
; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
|
|
; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
|
|
; SCCP: loop.body:
|
|
; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 200
|
|
; SCCP-NEXT: call void @use(i1 [[T_1]])
|
|
; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
|
|
; SCCP-NEXT: br label [[LOOP_HEADER]]
|
|
; SCCP: exit:
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @loop_with_header_2(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]]
|
|
; IPSCCP: loop.header:
|
|
; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
|
|
; IPSCCP: loop.body:
|
|
; IPSCCP-NEXT: call void @use(i1 true)
|
|
; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
|
|
; IPSCCP-NEXT: br label [[LOOP_HEADER]]
|
|
; IPSCCP: exit:
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i32 [0, %entry], [%iv.next, %loop.body]
|
|
%c.1 = icmp slt i32 %iv, 200
|
|
br i1 %c.1, label %loop.body, label %exit
|
|
|
|
loop.body:
|
|
%t.1 = icmp slt i32 %iv, 200
|
|
call void @use(i1 %t.1)
|
|
%iv.next = add nsw i32 %iv, 1
|
|
br label %loop.header
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; In the function below, the condition %c.1 results in a range [7, 6), which
|
|
; can be used as a widening bound. It does not fully contain the range we get
|
|
; from combining it with the information from %tmp12.
|
|
define void @foo(i64* %arg) {
|
|
; SCCP-LABEL: @foo(
|
|
; SCCP-NEXT: bb:
|
|
; SCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
|
|
; SCCP-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0
|
|
; SCCP-NEXT: [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8
|
|
; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
|
|
; SCCP-NEXT: i32 1, label [[BB3:%.*]]
|
|
; SCCP-NEXT: i32 2, label [[BB4:%.*]]
|
|
; SCCP-NEXT: i32 4, label [[BB19:%.*]]
|
|
; SCCP-NEXT: ]
|
|
; SCCP: bb3:
|
|
; SCCP-NEXT: unreachable
|
|
; SCCP: bb4:
|
|
; SCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
|
|
; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
|
|
; SCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
|
|
; SCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
|
|
; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
|
|
; SCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
|
|
; SCCP-NEXT: br label [[BB11:%.*]]
|
|
; SCCP: bb11:
|
|
; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
|
|
; SCCP-NEXT: br label [[BB13:%.*]]
|
|
; SCCP: bb13:
|
|
; SCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
|
|
; SCCP: bb15:
|
|
; SCCP-NEXT: unreachable
|
|
; SCCP: bb16:
|
|
; SCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2
|
|
; SCCP-NEXT: br label [[BB18]]
|
|
; SCCP: bb18:
|
|
; SCCP-NEXT: br label [[BB11]]
|
|
; SCCP: bb19:
|
|
; SCCP-NEXT: unreachable
|
|
; SCCP: bb20:
|
|
; SCCP-NEXT: ret void
|
|
;
|
|
; IPSCCP-LABEL: @foo(
|
|
; IPSCCP-NEXT: bb:
|
|
; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
|
|
; IPSCCP-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0
|
|
; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8
|
|
; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
|
|
; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
|
|
; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
|
|
; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
|
|
; IPSCCP-NEXT: ]
|
|
; IPSCCP: bb3:
|
|
; IPSCCP-NEXT: unreachable
|
|
; IPSCCP: bb4:
|
|
; IPSCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
|
|
; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
|
|
; IPSCCP-NEXT: [[TMP7:%.*]] = sub i64 3, [[TMP6]]
|
|
; IPSCCP-NEXT: [[TMP8:%.*]] = shl i64 [[TMP7]], 1
|
|
; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
|
|
; IPSCCP-NEXT: [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
|
|
; IPSCCP-NEXT: br label [[BB11:%.*]]
|
|
; IPSCCP: bb11:
|
|
; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
|
|
; IPSCCP-NEXT: br label [[BB13:%.*]]
|
|
; IPSCCP: bb13:
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
|
|
; IPSCCP: bb15:
|
|
; IPSCCP-NEXT: unreachable
|
|
; IPSCCP: bb16:
|
|
; IPSCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2
|
|
; IPSCCP-NEXT: br label [[BB18]]
|
|
; IPSCCP: bb18:
|
|
; IPSCCP-NEXT: br label [[BB11]]
|
|
; IPSCCP: bb19:
|
|
; IPSCCP-NEXT: unreachable
|
|
; IPSCCP: bb20:
|
|
; IPSCCP-NEXT: ret void
|
|
;
|
|
bb:
|
|
%tmp = zext i8 undef to i32
|
|
%tmp1 = getelementptr inbounds i64, i64* %arg, i32 0
|
|
%tmp2 = load i64, i64* %tmp1, align 8
|
|
switch i32 %tmp, label %bb20 [
|
|
i32 1, label %bb3
|
|
i32 2, label %bb4
|
|
i32 4, label %bb19
|
|
]
|
|
|
|
bb3: ; preds = %bb
|
|
unreachable
|
|
|
|
bb4: ; preds = %bb
|
|
%tmp5 = add i64 %tmp2, 3
|
|
%tmp6 = and i64 %tmp5, 3
|
|
%tmp7 = sub i64 3, %tmp6
|
|
%tmp8 = shl i64 %tmp7, 1
|
|
%tmp9 = trunc i64 %tmp8 to i32
|
|
%tmp10 = sext i32 %tmp9 to i64
|
|
br label %bb11
|
|
|
|
bb11: ; preds = %bb18, %bb4
|
|
%tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ]
|
|
br label %bb13
|
|
|
|
bb13: ; preds = %bb11
|
|
%c.1 = icmp eq i64 %tmp12, 6
|
|
br i1 %c.1, label %bb15, label %bb16
|
|
|
|
bb15: ; preds = %bb13
|
|
unreachable
|
|
|
|
bb16: ; preds = %bb13
|
|
%tmp17 = add i64 %tmp12, 2
|
|
br label %bb18
|
|
|
|
bb18: ; preds = %bb16
|
|
br label %bb11
|
|
|
|
bb19: ; preds = %bb
|
|
unreachable
|
|
|
|
bb20: ; preds = %bb
|
|
ret void
|
|
}
|
|
|
|
; The functions below check that widening with an upper bound does correctly
|
|
; return whether the range changed. Make sure we do not eliminate %c.2.
|
|
|
|
%struct.baz.1 = type { i32, i32, i8*, i8* }
|
|
%struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }>
|
|
|
|
@global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1
|
|
|
|
define linkonce_odr dereferenceable(1) i8* @spam(%struct.baz.1* %arg, i32 %arg1) align 2 {
|
|
; SCCP-LABEL: @spam(
|
|
; SCCP-NEXT: bb:
|
|
; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3
|
|
; SCCP-NEXT: [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8
|
|
; SCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
|
|
; SCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]]
|
|
; SCCP-NEXT: ret i8* [[TMP4]]
|
|
;
|
|
; IPSCCP-LABEL: @spam(
|
|
; IPSCCP-NEXT: bb:
|
|
; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3
|
|
; IPSCCP-NEXT: [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8
|
|
; IPSCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
|
|
; IPSCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]]
|
|
; IPSCCP-NEXT: ret i8* [[TMP4]]
|
|
;
|
|
bb:
|
|
%tmp = getelementptr inbounds %struct.baz.1, %struct.baz.1* %arg, i32 0, i32 3
|
|
%tmp2 = load i8*, i8** %tmp, align 8
|
|
%tmp3 = sext i32 %arg1 to i64
|
|
%tmp4 = getelementptr inbounds i8, i8* %tmp2, i64 %tmp3
|
|
ret i8* %tmp4
|
|
}
|
|
|
|
define i8* @wobble(%struct.blam.2* %arg, i32 %arg1) align 2 {
|
|
; SCCP-LABEL: @wobble(
|
|
; SCCP-NEXT: bb:
|
|
; SCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
|
|
; SCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
|
|
; SCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
|
|
; SCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
|
|
; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1
|
|
; SCCP-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8
|
|
; SCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
|
|
; SCCP-NEXT: br label [[BB8:%.*]]
|
|
; SCCP: bb8:
|
|
; SCCP-NEXT: [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
|
|
; SCCP-NEXT: [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ]
|
|
; SCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
|
|
; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
|
|
; SCCP: bb13:
|
|
; SCCP-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; SCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
|
|
; SCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
|
|
; SCCP-NEXT: [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]])
|
|
; SCCP-NEXT: [[TMP18]] = bitcast i8* [[TMP17]] to i16*
|
|
; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2
|
|
; SCCP-NEXT: [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1
|
|
; SCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
|
|
; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
|
|
; SCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
|
|
; SCCP: bb23:
|
|
; SCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; SCCP-NEXT: store i16 [[TMP24]], i16* [[TMP18]], align 2
|
|
; SCCP-NEXT: br label [[BB31]]
|
|
; SCCP: bb25:
|
|
; SCCP-NEXT: [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2
|
|
; SCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
|
|
; SCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
|
|
; SCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]]
|
|
; SCCP: bb29:
|
|
; SCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1
|
|
; SCCP-NEXT: br label [[BB8]]
|
|
; SCCP: bb31:
|
|
; SCCP-NEXT: [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
|
|
; SCCP-NEXT: [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
|
|
; SCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
|
|
; SCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
|
|
; SCCP: bb35:
|
|
; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1
|
|
; SCCP-NEXT: br label [[BB66:%.*]]
|
|
; SCCP: bb37:
|
|
; SCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
|
|
; SCCP: bb39:
|
|
; SCCP-NEXT: [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
|
|
; SCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; SCCP-NEXT: store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
|
|
; SCCP-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; SCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
|
|
; SCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
|
|
; SCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2
|
|
; SCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]])
|
|
; SCCP-NEXT: [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1
|
|
; SCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
|
|
; SCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1
|
|
; SCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4
|
|
; SCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2
|
|
; SCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]])
|
|
; SCCP-NEXT: [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1
|
|
; SCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
|
|
; SCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
|
|
; SCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
|
|
; SCCP: bb56:
|
|
; SCCP-NEXT: [[TMP57:%.*]] = add nsw i32 [[TMP40]], -1
|
|
; SCCP-NEXT: br label [[BB60]]
|
|
; SCCP: bb58:
|
|
; SCCP-NEXT: [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8*
|
|
; SCCP-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false)
|
|
; SCCP-NEXT: br label [[BB60]]
|
|
; SCCP: bb60:
|
|
; SCCP-NEXT: [[TMP61:%.*]] = phi i32 [ [[TMP57]], [[BB56]] ], [ [[TMP40]], [[BB39]] ], [ [[TMP11]], [[BB58]] ]
|
|
; SCCP-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; SCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1
|
|
; SCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4
|
|
; SCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]])
|
|
; SCCP-NEXT: br label [[BB66]]
|
|
; SCCP: bb66:
|
|
; SCCP-NEXT: [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
|
|
; SCCP-NEXT: ret i8* [[TMP67]]
|
|
;
|
|
; IPSCCP-LABEL: @wobble(
|
|
; IPSCCP-NEXT: bb:
|
|
; IPSCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
|
|
; IPSCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
|
|
; IPSCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
|
|
; IPSCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
|
|
; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1
|
|
; IPSCCP-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8
|
|
; IPSCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
|
|
; IPSCCP-NEXT: br label [[BB8:%.*]]
|
|
; IPSCCP: bb8:
|
|
; IPSCCP-NEXT: [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
|
|
; IPSCCP-NEXT: [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ]
|
|
; IPSCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
|
|
; IPSCCP: bb13:
|
|
; IPSCCP-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; IPSCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
|
|
; IPSCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
|
|
; IPSCCP-NEXT: [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]])
|
|
; IPSCCP-NEXT: [[TMP18]] = bitcast i8* [[TMP17]] to i16*
|
|
; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2
|
|
; IPSCCP-NEXT: [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1
|
|
; IPSCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
|
|
; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
|
|
; IPSCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
|
|
; IPSCCP: bb23:
|
|
; IPSCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; IPSCCP-NEXT: store i16 [[TMP24]], i16* [[TMP18]], align 2
|
|
; IPSCCP-NEXT: br label [[BB31]]
|
|
; IPSCCP: bb25:
|
|
; IPSCCP-NEXT: [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2
|
|
; IPSCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
|
|
; IPSCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
|
|
; IPSCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]]
|
|
; IPSCCP: bb29:
|
|
; IPSCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1
|
|
; IPSCCP-NEXT: br label [[BB8]]
|
|
; IPSCCP: bb31:
|
|
; IPSCCP-NEXT: [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
|
|
; IPSCCP-NEXT: [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
|
|
; IPSCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
|
|
; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
|
|
; IPSCCP: bb35:
|
|
; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1
|
|
; IPSCCP-NEXT: br label [[BB66:%.*]]
|
|
; IPSCCP: bb37:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
|
|
; IPSCCP: bb39:
|
|
; IPSCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; IPSCCP-NEXT: store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
|
|
; IPSCCP-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7
|
|
; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
|
|
; IPSCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2
|
|
; IPSCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]])
|
|
; IPSCCP-NEXT: [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1
|
|
; IPSCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
|
|
; IPSCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1
|
|
; IPSCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4
|
|
; IPSCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2
|
|
; IPSCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]])
|
|
; IPSCCP-NEXT: [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1
|
|
; IPSCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
|
|
; IPSCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
|
|
; IPSCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
|
|
; IPSCCP: bb56:
|
|
; IPSCCP-NEXT: br label [[BB60]]
|
|
; IPSCCP: bb58:
|
|
; IPSCCP-NEXT: [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8*
|
|
; IPSCCP-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false)
|
|
; IPSCCP-NEXT: br label [[BB60]]
|
|
; IPSCCP: bb60:
|
|
; IPSCCP-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ]
|
|
; IPSCCP-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
|
|
; IPSCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1
|
|
; IPSCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4
|
|
; IPSCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]])
|
|
; IPSCCP-NEXT: br label [[BB66]]
|
|
; IPSCCP: bb66:
|
|
; IPSCCP-NEXT: [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
|
|
; IPSCCP-NEXT: ret i8* [[TMP67]]
|
|
;
|
|
bb:
|
|
%tmp = lshr i32 %arg1, 16
|
|
%tmp2 = xor i32 %tmp, %arg1
|
|
%tmp3 = and i32 %tmp2, 65535
|
|
%tmp4 = mul i32 %arg1, 8
|
|
%tmp5 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 1
|
|
%tmp6 = load i32, i32* %tmp5, align 8
|
|
%tmp7 = and i32 %tmp4, %tmp6
|
|
br label %bb8
|
|
|
|
bb8: ; preds = %bb29, %bb
|
|
%tmp9 = phi i8* [ undef, %bb ], [ %tmp17, %bb29 ]
|
|
%tmp10 = phi i16* [ undef, %bb ], [ %tmp18, %bb29 ]
|
|
%tmp11 = phi i32 [ 0, %bb ], [ %tmp30, %bb29 ]
|
|
%c.1 = icmp slt i32 %tmp11, 8
|
|
br i1 %c.1, label %bb13, label %bb31
|
|
|
|
bb13: ; preds = %bb8
|
|
%tmp14 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
|
|
%tmp15 = add i32 %tmp7, %tmp11
|
|
%tmp16 = mul i32 %tmp15, 4
|
|
%tmp17 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp14, i32 %tmp16)
|
|
%tmp18 = bitcast i8* %tmp17 to i16*
|
|
%tmp19 = getelementptr inbounds i8, i8* %tmp17, i64 2
|
|
%tmp20 = load i8, i8* %tmp19, align 1
|
|
%tmp21 = zext i8 %tmp20 to i32
|
|
%tmp22 = icmp eq i32 %tmp21, 0
|
|
br i1 %tmp22, label %bb23, label %bb25
|
|
|
|
bb23: ; preds = %bb13
|
|
%tmp24 = trunc i32 %tmp3 to i16
|
|
store i16 %tmp24, i16* %tmp18, align 2
|
|
br label %bb31
|
|
|
|
bb25: ; preds = %bb13
|
|
%tmp26 = load i16, i16* %tmp18, align 2
|
|
%tmp27 = zext i16 %tmp26 to i32
|
|
%tmp28 = icmp eq i32 %tmp27, %tmp3
|
|
br i1 %tmp28, label %bb31, label %bb29
|
|
|
|
bb29: ; preds = %bb25
|
|
%tmp30 = add nsw i32 %tmp11, 1
|
|
br label %bb8
|
|
|
|
bb31: ; preds = %bb25, %bb23, %bb8
|
|
%tmp32 = phi i8* [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp9, %bb8 ]
|
|
%tmp33 = phi i16* [ %tmp18, %bb23 ], [ %tmp18, %bb25 ], [ %tmp10, %bb8 ]
|
|
%tmp34 = icmp eq i32 %tmp11, 0
|
|
br i1 %tmp34, label %bb35, label %bb37
|
|
|
|
bb35: ; preds = %bb31
|
|
%tmp36 = getelementptr inbounds i8, i8* %tmp32, i64 1
|
|
br label %bb66
|
|
|
|
bb37: ; preds = %bb31
|
|
%c.2 = icmp eq i32 %tmp11, 8
|
|
br i1 %c.2, label %bb39, label %bb58
|
|
|
|
bb39: ; preds = %bb37
|
|
%tmp40 = add nsw i32 %tmp11, -1
|
|
%tmp41 = trunc i32 %tmp3 to i16
|
|
store i16 %tmp41, i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
|
|
%tmp42 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
|
|
%tmp43 = add i32 %tmp7, %tmp40
|
|
%tmp44 = mul i32 %tmp43, 4
|
|
%tmp45 = add i32 %tmp44, 2
|
|
%tmp46 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp45)
|
|
%tmp47 = load i8, i8* %tmp46, align 1
|
|
%tmp48 = zext i8 %tmp47 to i32
|
|
%tmp49 = sub i32 %tmp43, 1
|
|
%tmp50 = mul i32 %tmp49, 4
|
|
%tmp51 = add i32 %tmp50, 2
|
|
%tmp52 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp51)
|
|
%tmp53 = load i8, i8* %tmp52, align 1
|
|
%tmp54 = zext i8 %tmp53 to i32
|
|
%tmp55 = icmp sgt i32 %tmp48, %tmp54
|
|
br i1 %tmp55, label %bb56, label %bb60
|
|
|
|
bb56: ; preds = %bb39
|
|
%tmp57 = add nsw i32 %tmp40, -1
|
|
br label %bb60
|
|
|
|
bb58: ; preds = %bb37
|
|
%tmp59 = bitcast i16* %tmp33 to i8*
|
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 %tmp59, i64 4, i1 false)
|
|
br label %bb60
|
|
|
|
bb60: ; preds = %bb58, %bb56, %bb39
|
|
%tmp61 = phi i32 [ %tmp57, %bb56 ], [ %tmp40, %bb39 ], [ %tmp11, %bb58 ]
|
|
%tmp62 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
|
|
%tmp63 = add i32 %tmp7, 1
|
|
%tmp64 = mul i32 %tmp63, 4
|
|
%tmp65 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp62, i32 %tmp64)
|
|
br label %bb66
|
|
|
|
bb66: ; preds = %bb60, %bb35
|
|
%tmp67 = phi i8* [ %tmp36, %bb35 ], [ null, %bb60 ]
|
|
ret i8* %tmp67
|
|
}
|
|
|
|
|
|
define i32 @loop_with_multiple_euqal_incomings(i32 %N) {
|
|
; SCCP-LABEL: @loop_with_multiple_euqal_incomings(
|
|
; SCCP-NEXT: entry:
|
|
; SCCP-NEXT: br label [[LOOP:%.*]]
|
|
; SCCP: loop:
|
|
; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
|
|
; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
|
; SCCP: bb1:
|
|
; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]]
|
|
; SCCP: bb2:
|
|
; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]]
|
|
; SCCP: bb3:
|
|
; SCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1
|
|
; SCCP-NEXT: br label [[LOOP]]
|
|
; SCCP: bb4:
|
|
; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; SCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
|
|
; SCCP: bb5:
|
|
; SCCP-NEXT: br label [[LOOP]]
|
|
; SCCP: bb6:
|
|
; SCCP-NEXT: br label [[LOOP]]
|
|
; SCCP: end:
|
|
; SCCP-NEXT: ret i32 [[P]]
|
|
;
|
|
; IPSCCP-LABEL: @loop_with_multiple_euqal_incomings(
|
|
; IPSCCP-NEXT: entry:
|
|
; IPSCCP-NEXT: br label [[LOOP:%.*]]
|
|
; IPSCCP: loop:
|
|
; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
|
|
; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
|
; IPSCCP: bb1:
|
|
; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]]
|
|
; IPSCCP: bb2:
|
|
; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]]
|
|
; IPSCCP: bb3:
|
|
; IPSCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1
|
|
; IPSCCP-NEXT: br label [[LOOP]]
|
|
; IPSCCP: bb4:
|
|
; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
|
|
; IPSCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
|
|
; IPSCCP: bb5:
|
|
; IPSCCP-NEXT: br label [[LOOP]]
|
|
; IPSCCP: bb6:
|
|
; IPSCCP-NEXT: br label [[LOOP]]
|
|
; IPSCCP: end:
|
|
; IPSCCP-NEXT: ret i32 [[P]]
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%p = phi i32 [ 0, %entry ], [ %p.next, %bb3 ], [ 0, %bb4 ], [ 0, %bb5], [ 0, %bb6 ]
|
|
%c.1 = call i1 @cond()
|
|
br i1 %c.1, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
%c.2 = call i1 @cond()
|
|
br i1 %c.2, label %bb3, label %bb4
|
|
|
|
bb2:
|
|
%c.4 = call i1 @cond()
|
|
br i1 %c.4, label %bb5, label %bb6
|
|
|
|
bb3:
|
|
%p.next = add i32 %p, 1
|
|
br label %loop
|
|
|
|
bb4:
|
|
%c.3 = call i1 @cond()
|
|
br i1 %c.3, label %loop, label %end
|
|
|
|
bb5:
|
|
br label %loop
|
|
|
|
bb6:
|
|
br label %loop
|
|
|
|
end:
|
|
ret i32 %p
|
|
}
|