Last active
December 2, 2021 22:18
-
-
Save minglotus-6/a05ac0300d8ea8204ec9eed409951b25 to your computer and use it in GitHub Desktop.
llvm/test/Transforms/SROA/alloca-struct.ll by update_check_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
; 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: | |
; CHECK-NEXT: br i1 [[TEST:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | |
; CHECK: if.then: | |
; CHECK-NEXT: br label [[RETURN:%.*]] | |
; CHECK: if.end: | |
; CHECK-NEXT: [[CALL:%.*]] = call i64 [[P:%.*]]() | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[CALL]] to i32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[CALL]], 32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[RETVAL_SROA_3_0_EXTRACT_SHIFT]] to i8 | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[CALL]], 40 | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[RETVAL_SROA_4_0_EXTRACT_SHIFT]] to i24 | |
; CHECK-NEXT: br label [[RETURN]] | |
; CHECK: return: | |
; CHECK-NEXT: [[RETVAL_SROA_4_SROA_0_0:%.*]] = phi i24 [ undef, [[IF_THEN]] ], [ [[RETVAL_SROA_4_0_EXTRACT_TRUNC]], [[IF_END]] ] | |
; CHECK-NEXT: [[RETVAL_SROA_3_0:%.*]] = phi i8 [ 0, [[IF_THEN]] ], [ [[RETVAL_SROA_3_0_EXTRACT_TRUNC]], [[IF_END]] ] | |
; CHECK-NEXT: [[RETVAL_SROA_0_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[RETVAL_SROA_0_0_EXTRACT_TRUNC]], [[IF_END]] ] | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_INSERT_EXT:%.*]] = zext i24 [[RETVAL_SROA_4_SROA_0_0]] to i64 | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_INSERT_SHIFT:%.*]] = shl i64 [[RETVAL_SROA_4_0_INSERT_EXT]], 40 | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_INSERT_MASK:%.*]] = and i64 undef, 1099511627775 | |
; CHECK-NEXT: [[RETVAL_SROA_4_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_4_0_INSERT_MASK]], [[RETVAL_SROA_4_0_INSERT_SHIFT]] | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_EXT:%.*]] = zext i8 [[RETVAL_SROA_3_0]] to i64 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[RETVAL_SROA_3_0_INSERT_EXT]], 32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_4_0_INSERT_INSERT]], -1095216660481 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_3_0_INSERT_MASK]], [[RETVAL_SROA_3_0_INSERT_SHIFT]] | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[RETVAL_SROA_0_0]] to i64 | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_3_0_INSERT_INSERT]], -4294967296 | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_0_0_INSERT_MASK]], [[RETVAL_SROA_0_0_INSERT_EXT]] | |
; CHECK-NEXT: ret i64 [[RETVAL_SROA_0_0_INSERT_INSERT]] | |
; | |
; COM: Check that registers are used and alloca instructions are eliminated. | |
; COM: Check there are more than one PHI nodes to select scalarized values. | |
; CHECK-COUNT-3: phi | |
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-NEXT: br i1 [[TEST:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | |
; CHECK: if.then: | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_MASK:%.*]] = and i64 undef, -4294967296 | |
; CHECK-NEXT: [[RETVAL_SROA_0_4_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_0_0_INSERT_MASK]], 4294967295 | |
; CHECK-NEXT: br label [[RETURN:%.*]] | |
; CHECK: if.end: | |
; CHECK-NEXT: [[CALL:%.*]] = call i64 [[P:%.*]]() | |
; CHECK-NEXT: br label [[RETURN]] | |
; CHECK: return: | |
; CHECK-NEXT: [[RETVAL_SROA_0_0:%.*]] = phi i64 [ [[RETVAL_SROA_0_4_INSERT_MASK]], [[IF_THEN]] ], [ [[CALL]], [[IF_END]] ] | |
; CHECK-NEXT: ret i64 [[RETVAL_SROA_0_0]] | |
; | |
; COM: Check that there is only PHI node to select the whole value. | |
; CHECK-COUNT-1: phi | |
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-NEXT: [[CALL:%.*]] = call i64 @time(i64* null) | |
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[CALL]] to i32 | |
; CHECK-NEXT: call void @srand(i32 [[CONV]]) | |
; CHECK-NEXT: br i1 [[TEST:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | |
; CHECK: if.then: | |
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @rand() | |
; CHECK-NEXT: br label [[RETURN:%.*]] | |
; CHECK: if.end: | |
; CHECK-NEXT: [[CALL2:%.*]] = call i64 [[P:%.*]]() | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[CALL2]] to i32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[CALL2]], 32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[RETVAL_SROA_3_0_EXTRACT_SHIFT]] to i32 | |
; CHECK-NEXT: br label [[RETURN]] | |
; CHECK: return: | |
; CHECK-NEXT: [[RETVAL_SROA_3_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[RETVAL_SROA_3_0_EXTRACT_TRUNC]], [[IF_END]] ] | |
; CHECK-NEXT: [[RETVAL_SROA_0_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[RETVAL_SROA_0_0_EXTRACT_TRUNC]], [[IF_END]] ] | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_EXT:%.*]] = zext i32 [[RETVAL_SROA_3_0]] to i64 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_SHIFT:%.*]] = shl i64 [[RETVAL_SROA_3_0_INSERT_EXT]], 32 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_MASK:%.*]] = and i64 undef, 4294967295 | |
; CHECK-NEXT: [[RETVAL_SROA_3_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_3_0_INSERT_MASK]], [[RETVAL_SROA_3_0_INSERT_SHIFT]] | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[RETVAL_SROA_0_0]] to i64 | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_MASK:%.*]] = and i64 [[RETVAL_SROA_3_0_INSERT_INSERT]], -4294967296 | |
; CHECK-NEXT: [[RETVAL_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[RETVAL_SROA_0_0_INSERT_MASK]], [[RETVAL_SROA_0_0_INSERT_EXT]] | |
; CHECK-NEXT: ret i64 [[RETVAL_SROA_0_0_INSERT_INSERT]] | |
; | |
; CHECK-COUNT-2: phi i32 | |
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment