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

Mingming Liu via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 19 10:17:56 PST 2021


Author: Mingming Liu
Date: 2021-11-19T18:16:49Z
New Revision: ffdace4892bd1f43121d365c22eb9c3fe79aeb6c

URL: https://github.com/llvm/llvm-project/commit/ffdace4892bd1f43121d365c22eb9c3fe79aeb6c
DIFF: https://github.com/llvm/llvm-project/commit/ffdace4892bd1f43121d365c22eb9c3fe79aeb6c.diff

LOG: [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

Added: 
    llvm/test/Transforms/SROA/alloca-struct.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SROA/alloca-struct.ll b/llvm/test/Transforms/SROA/alloca-struct.ll
new file mode 100644
index 0000000000000..17257ea6cdc10
--- /dev/null
+++ b/llvm/test/Transforms/SROA/alloca-struct.ll
@@ -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()


        


More information about the llvm-commits mailing list