We outline what the IRSimilarityIdentifier deems GEP Instructions to be similar. In this case, the types must be the same, and the operand values after the first indexing operand must be the exact same. Tests: Removing test/Transforms/IROutliner/illegal-gep.ll Adding test/Transforms/IROutliner/outlining-gep.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87317
69 lines
2.5 KiB
LLVM
69 lines
2.5 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s
|
|
|
|
; This test checks to make sure that we outline getelementptr instructions only
|
|
; when all the operands after the first are the exact same. In this case, we
|
|
; outline from the first two functions, but not the third.
|
|
|
|
%struct.RT = type { i8, [10 x [20 x i32]], i8 }
|
|
%struct.ST = type { i32, double, %struct.RT }
|
|
|
|
define void @function1(%struct.ST* %s, i64 %t) {
|
|
; CHECK-LABEL: @function1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], %struct.ST* [[S:%.*]], i64 [[T:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
%b = alloca i32, align 4
|
|
store i32 2, i32* %a, align 4
|
|
store i32 3, i32* %b, align 4
|
|
%0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %t, i32 1
|
|
ret void
|
|
}
|
|
|
|
define void @function2(%struct.ST* %s, i64 %t) {
|
|
; CHECK-LABEL: @function2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], %struct.ST* [[S:%.*]], i64 [[T:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
%b = alloca i32, align 4
|
|
store i32 2, i32* %a, align 4
|
|
store i32 3, i32* %b, align 4
|
|
%0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %t, i32 1
|
|
ret void
|
|
}
|
|
|
|
define void @function3(%struct.ST* %s, i64 %t) {
|
|
; CHECK-LABEL: @function3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 2, i32* [[A]], align 4
|
|
; CHECK-NEXT: store i32 3, i32* [[B]], align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S:%.*]], i64 [[T:%.*]], i32 0
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
%b = alloca i32, align 4
|
|
store i32 2, i32* %a, align 4
|
|
store i32 3, i32* %b, align 4
|
|
%0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %t, i32 0
|
|
ret void
|
|
}
|
|
|
|
; CHECK: define internal void @outlined_ir_func_0(i32* [[ARG0:%.*]], i32* [[ARG1:%.*]], %struct.ST* [[ARG2:%.*]], i64 [[ARG3:%.*]])
|
|
; CHECK: entry_to_outline:
|
|
; CHECK-NEXT: store i32 2, i32* [[ARG0]], align 4
|
|
; CHECK-NEXT: store i32 3, i32* [[ARG1]], align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds %struct.ST, %struct.ST* [[ARG2]], i64 [[ARG3]], i32 1
|