Files
clang-p2996/llvm/test/Transforms/IROutliner/phi-nodes-parent-block-referential.ll
Andrew Litteken 4e500df89e [IROutliner] Fix phi nodes when self referential within block but doesn't contain branch
When outlining a phi node, if the the incoming branch is a block contained in the region and the branch from that block is not outlined, we create broken code. The fix is to recognize when that branch from the included incoming block is not contained, and ignore the region.

Reviewer: paquette

Differential Revision: https://reviews.llvm.org/D121311
2022-03-21 11:05:15 -05:00

101 lines
3.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s
; Show that we do not outline when all of the phi nodes in the beginning
; block are included not in the region.
define void @function1(i32* %a, i32* %b) {
entry:
%0 = alloca i32, align 4
%c = load i32, i32* %0, align 4
%y = add i32 %c, %c
br label %test1
dummy:
ret void
test1:
%1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
%2 = phi i32 [ %e, %test1 ], [ %y, %entry ]
%e = load i32, i32* %0, align 4
%3 = add i32 %c, %c
%4 = sub i32 %c, %c
br i1 true, label %first, label %test1
first:
ret void
}
define void @function2(i32* %a, i32* %b) {
entry:
%0 = alloca i32, align 4
%c = load i32, i32* %0, align 4
%y = mul i32 %c, %c
br label %test1
dummy:
ret void
test1:
%1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
%2 = phi i32 [ %y, %entry ], [ %e, %test1 ]
%e = load i32, i32* %0, align 4
%3 = add i32 %c, %c
%4 = mul i32 %c, %c
br i1 true, label %first, label %test1
first:
ret void
}
; CHECK-LABEL: @function1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[E_LOC:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[TMP0]], align 4
; CHECK-NEXT: [[Y:%.*]] = add i32 [[C]], [[C]]
; CHECK-NEXT: br label [[TEST1:%.*]]
; CHECK: dummy:
; CHECK-NEXT: ret void
; CHECK: test1:
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[E_RELOAD]], [[TEST1]] ], [ [[Y]], [[ENTRY]] ]
; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i32* [[E_LOC]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]])
; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[TMP0]], i32 [[C]], i32* [[E_LOC]])
; CHECK-NEXT: [[E_RELOAD]] = load i32, i32* [[E_LOC]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[LT_CAST]])
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[C]], [[C]]
; CHECK-NEXT: br i1 true, label [[FIRST:%.*]], label [[TEST1]]
; CHECK: first:
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: @function2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[E_LOC:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[TMP0]], align 4
; CHECK-NEXT: [[Y:%.*]] = mul i32 [[C]], [[C]]
; CHECK-NEXT: br label [[TEST1:%.*]]
; CHECK: dummy:
; CHECK-NEXT: ret void
; CHECK: test1:
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[Y]], [[ENTRY]] ], [ [[E_RELOAD]], [[TEST1]] ]
; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i32* [[E_LOC]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]])
; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[TMP0]], i32 [[C]], i32* [[E_LOC]])
; CHECK-NEXT: [[E_RELOAD]] = load i32, i32* [[E_LOC]], align 4
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[LT_CAST]])
; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[C]], [[C]]
; CHECK-NEXT: br i1 true, label [[FIRST:%.*]], label [[TEST1]]
; CHECK: first:
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define internal void @outlined_ir_func_0(
; CHECK-NEXT: newFuncRoot:
; CHECK-NEXT: br label [[TEST1_TO_OUTLINE:%.*]]
; CHECK: test1_to_outline:
; CHECK-NEXT: [[E:%.*]] = load i32, i32* [[TMP0:%.*]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP1:%.*]], [[TMP1]]
; CHECK-NEXT: br label [[TEST1_AFTER_OUTLINE_EXITSTUB:%.*]]
; CHECK: test1_after_outline.exitStub:
; CHECK-NEXT: store i32 [[E]], i32* [[TMP2:%.*]], align 4
; CHECK-NEXT: ret void
;