Skip to content

Instantly share code, notes, and snippets.

@minglotus-6
Last active December 2, 2021 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minglotus-6/a05ac0300d8ea8204ec9eed409951b25 to your computer and use it in GitHub Desktop.
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
; 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