[SROA] Add new test cases to cover existing SROA behavior that structs will be scalarized.

Add an IR in unit test directory, which demonstrate the scalarization for struct allocations.
This is added to pave the way for an SROA change to skip scalarization for some cases.

Reviewed By: davidxl

Differential Revision: https://reviews.llvm.org/D114128
This commit is contained in:
Mingming Liu 2021-11-19 18:16:11 +00:00
parent 7eec832def
commit ffdace4892
1 changed files with 139 additions and 0 deletions

View File

@ -0,0 +1,139 @@
; RUN: opt < %s -sroa -S | FileCheck %s
; RUN: opt < %s -passes=sroa -S | FileCheck %s
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.RetValIntChar = type { i32, i8 }
%struct.RetValTwoInts = type { i32, i32 }
%struct.RetValOneIntTwoChar = type { i32, i8 }
; Tests that a struct of type {i32, i8} is scalarized by SROA.
; FIXME: SROA should skip scalarization since there is no scalar access.
; Currently scalarization happens due to the mismatch of allocated size
; and the actual structure size.
define i64 @test_struct_of_int_char(i1 zeroext %test, i64 ()* %p) {
; CHECK-LABEL: @test_struct_of_int_char(
; CHECK-NEXT: entry:
; COM: Check that registers are used and alloca instructions are eliminated.
; CHECK-NOT: alloca
; CHECK: if.then:
; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: if.end:
; CHECK-NEXT: call i64 [[P:%.*]]()
; CHECK: br label [[RETURN]]
; CHECK: return:
; COM: Check there are more than one PHI nodes to select scalarized values.
; CHECK-COUNT-3: phi
; CHECK: ret i64
;
entry:
%retval = alloca %struct.RetValIntChar, align 4
br i1 %test, label %if.then, label %if.end
if.then: ; preds = %entry
%x = getelementptr inbounds %struct.RetValIntChar, %struct.RetValIntChar* %retval, i32 0, i32 0
store i32 0, i32* %x, align 4
%y = getelementptr inbounds %struct.RetValIntChar, %struct.RetValIntChar* %retval, i32 0, i32 1
store i8 0, i8* %y, align 4
br label %return
if.end: ; preds = %entry
%call = call i64 %p()
%0 = bitcast %struct.RetValIntChar* %retval to i64*
store i64 %call, i64* %0, align 4
br label %return
return: ; preds = %if.end, %if.then
%1 = bitcast %struct.RetValIntChar* %retval to i64*
%2 = load i64, i64* %1, align 4
ret i64 %2
}
; Test that the alloca of struct{int, int} will be scalarized by SROA.
define i64 @test_struct_of_two_int(i1 zeroext %test, i64 ()* %p) {
; CHECK-LABEL: @test_struct_of_two_int(
; CHECK-NEXT: entry:
; CHECK-NOT: alloca
; CHECK: if.then:
; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: if.end:
; CHECK-NEXT: call i64
; CHECK: return:
; COM: Check that there are more than one PHI nodes to select the scalarized values.
; CHECK-COUNT-2: phi
; CHECK: ret i64
;
entry:
%retval = alloca %struct.RetValTwoInts, align 4
br i1 %test, label %if.then, label %if.end
if.then: ; preds = %entry
%x = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 0
store i32 0, i32* %x, align 4
%y = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 1
store i32 0, i32* %y, align 4
br label %return
if.end: ; preds = %entry
%call = call i64 %p()
%0 = bitcast %struct.RetValTwoInts* %retval to i64*
store i64 %call, i64* %0, align 4
br label %return
return: ; preds = %if.end, %if.then
%1 = bitcast %struct.RetValTwoInts* %retval to i64*
%2 = load i64, i64* %1, align 4
ret i64 %2
}
; Tests that allocated struct type is scalarized when non-constant values are
; stored into its fields.
define i64 @test_one_field_has_runtime_value(i1 zeroext %test, i64 ()* %p) {
; CHECK-LABEL: @test_one_field_has_runtime_value(
; CHECK-NEXT: entry:
; CHECK-NOT: alloca
; CHECK: call void @srand
; CHECK: if.then:
; CHECK-NEXT: call i32 @rand()
; CHECK-NEXT: br label
; CHECK: if.end:
; CHECK-NEXT: call i64
; CHECK: return:
; CHECK-COUNT-2: phi i32
; CHECK: ret i64
;
entry:
%retval = alloca %struct.RetValTwoInts, align 4
%call = call i64 @time(i64* null)
%conv = trunc i64 %call to i32
call void @srand(i32 %conv)
br i1 %test, label %if.then, label %if.end
if.then: ; preds = %entry
%x = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 0
%call1 = call i32 @rand()
store i32 %call1, i32* %x, align 4
%y = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 1
store i32 1, i32* %y, align 4
br label %return
if.end: ; preds = %entry
%call2 = call i64 %p()
%0 = bitcast %struct.RetValTwoInts* %retval to i64*
store i64 %call2, i64* %0, align 4
br label %return
return: ; preds = %if.end, %if.then
%1 = bitcast %struct.RetValTwoInts* %retval to i64*
%2 = load i64, i64* %1, align 4
ret i64 %2
}
; Function Attrs: nounwind
declare void @srand(i32)
; Function Attrs: nounwind
declare i64 @time(i64*)
; Function Attrs: nounwind
declare i32 @rand()