blob: 688338bfb77fc0a6328656e7b228fe3ac04a9944 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes=loop-fusion < %s | FileCheck %s
; Test that loop-fusion does not crash on functions with indirectbr and
; loops that lack a preheader (or other required loop structure).
define i32 @foo(ptr nocapture readonly %p) {
; CHECK-LABEL: define i32 @foo(
; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TBL:%.*]] = alloca <2 x ptr>, align 16
; CHECK-NEXT: store <2 x ptr> <ptr blockaddress(@foo, %[[INDIRECT:.*]]), ptr blockaddress(@foo, %[[EXIT:.*]])>, ptr [[TBL]], align 16
; CHECK-NEXT: br label %[[FOR_COND:.*]]
; CHECK: [[FOR_COND]]:
; CHECK-NEXT: [[CUR:%.*]] = phi ptr [ [[P]], %[[ENTRY]] ], [ [[NEXT:%.*]], %[[FOR_COND]] ]
; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[CUR]], align 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[VAL]], 7
; CHECK-NEXT: [[NEXT]] = getelementptr inbounds i8, ptr [[CUR]], i64 1
; CHECK-NEXT: br i1 [[CMP]], label %[[INDIRECT_PREHEADER:.*]], label %[[FOR_COND]]
; CHECK: [[INDIRECT_PREHEADER]]:
; CHECK-NEXT: [[RAW:%.*]] = load i8, ptr [[NEXT]], align 1
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[RAW]] to i64
; CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds <2 x ptr>, ptr [[TBL]], i64 0, i64 [[IDX]]
; CHECK-NEXT: [[DEST:%.*]] = load ptr, ptr [[SLOT]], align 8
; CHECK-NEXT: br label %[[INDIRECT]]
; CHECK: [[INDIRECT]]:
; CHECK-NEXT: indirectbr ptr [[DEST]], [label %[[INDIRECT]], label %[[EXIT]]]
; CHECK: [[INDIRECT2:.*:]]
; CHECK-NEXT: indirectbr ptr [[DEST]], [label %[[INDIRECT]], label %[[EXIT]]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret i32 0
;
entry:
%tbl = alloca <2 x ptr>, align 16
store <2 x ptr> <ptr blockaddress(@foo, %indirect), ptr blockaddress(@foo, %exit)>, ptr %tbl, align 16
br label %for.cond
for.cond: ; preds = %for.cond, %entry
%cur = phi ptr [ %p, %entry ], [ %next, %for.cond ]
%val = load i8, ptr %cur, align 1
%cmp = icmp eq i8 %val, 7
%next = getelementptr inbounds i8, ptr %cur, i64 1
br i1 %cmp, label %indirect.preheader, label %for.cond
indirect.preheader: ; preds = %for.cond
%raw = load i8, ptr %next, align 1
%idx = sext i8 %raw to i64
%slot = getelementptr inbounds <2 x ptr>, ptr %tbl, i64 0, i64 %idx
%dest = load ptr, ptr %slot, align 8
br label %indirect
indirect:
indirectbr ptr %dest, [label %indirect, label %exit]
indirect2:
indirectbr ptr %dest, [label %indirect, label %exit]
exit:
ret i32 0
}