This introduces the DXILMemIntrinsics pass and moves memset and memcpy handling from DXILLegalize to here. We need to do this so that we can handle memory intrinsics before the DXILResourceAccess pass so that we can properly deal with arrays and large structures in resources.
101 lines
4.4 KiB
LLVM
101 lines
4.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -S -dxil-mem-intrinsics -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
|
|
|
|
define void @replace_float_memset_test() #0 {
|
|
; CHECK-LABEL: define void @replace_float_memset_test(
|
|
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[ACCUM_I_FLAT:%.*]] = alloca [2 x float], align 4
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x float], ptr [[ACCUM_I_FLAT]], i32 0, i32 0
|
|
; CHECK-NEXT: store float 0.000000e+00, ptr [[GEP]], align 4
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [2 x float], ptr [[ACCUM_I_FLAT]], i32 0, i32 1
|
|
; CHECK-NEXT: store float 0.000000e+00, ptr [[GEP1]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%accum.i.flat = alloca [2 x float], align 4
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(8) %accum.i.flat, i8 0, i32 8, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @replace_half_memset_test() #0 {
|
|
; CHECK-LABEL: define void @replace_half_memset_test(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ACCUM_I_FLAT:%.*]] = alloca [2 x half], align 4
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x half], ptr [[ACCUM_I_FLAT]], i32 0, i32 0
|
|
; CHECK-NEXT: store half 0xH0000, ptr [[GEP]], align 2
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [2 x half], ptr [[ACCUM_I_FLAT]], i32 0, i32 1
|
|
; CHECK-NEXT: store half 0xH0000, ptr [[GEP1]], align 2
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%accum.i.flat = alloca [2 x half], align 4
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(8) %accum.i.flat, i8 0, i32 4, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @replace_double_memset_test() #0 {
|
|
; CHECK-LABEL: define void @replace_double_memset_test(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ACCUM_I_FLAT:%.*]] = alloca [2 x double], align 4
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x double], ptr [[ACCUM_I_FLAT]], i32 0, i32 0
|
|
; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP]], align 8
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [2 x double], ptr [[ACCUM_I_FLAT]], i32 0, i32 1
|
|
; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP1]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%accum.i.flat = alloca [2 x double], align 4
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(8) %accum.i.flat, i8 0, i32 16, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @replace_int16_memset_test() #0 {
|
|
; CHECK-LABEL: define void @replace_int16_memset_test(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[CACHE_I:%.*]] = alloca [2 x i16], align 2
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x i16], ptr [[CACHE_I]], i32 0, i32 0
|
|
; CHECK-NEXT: store i16 0, ptr [[GEP]], align 2
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [2 x i16], ptr [[CACHE_I]], i32 0, i32 1
|
|
; CHECK-NEXT: store i16 0, ptr [[GEP1]], align 2
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%cache.i = alloca [2 x i16], align 2
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 2 dereferenceable(4) %cache.i, i8 0, i32 4, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @replace_int_memset_test() #0 {
|
|
; CHECK-LABEL: define void @replace_int_memset_test(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ACCUM_I_FLAT:%.*]] = alloca [1 x i32], align 4
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [1 x i32], ptr [[ACCUM_I_FLAT]], i32 0, i32 0
|
|
; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%accum.i.flat = alloca [1 x i32], align 4
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(8) %accum.i.flat, i8 0, i32 4, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @replace_int_memset_to_var_test() #0 {
|
|
; CHECK-LABEL: define void @replace_int_memset_to_var_test(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[ACCUM_I_FLAT:%.*]] = alloca [1 x i32], align 4
|
|
; CHECK-NEXT: [[I:%.*]] = alloca i8, align 4
|
|
; CHECK-NEXT: store i8 1, ptr [[I]], align 1
|
|
; CHECK-NEXT: [[I8_LOAD1:%.*]] = load i8, ptr [[I]], align 1
|
|
; CHECK-NEXT: [[I8_LOAD:%.*]] = zext i8 [[I8_LOAD1]] to i32
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [1 x i32], ptr [[ACCUM_I_FLAT]], i32 0, i32 0
|
|
; CHECK-NEXT: store i32 [[I8_LOAD]], ptr [[GEP]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%accum.i.flat = alloca [1 x i32], align 4
|
|
%i = alloca i8, align 4
|
|
store i8 1, ptr %i
|
|
%i8.load = load i8, ptr %i
|
|
call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(8) %accum.i.flat, i8 %i8.load, i32 4, i1 false)
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = {"hlsl.export"}
|
|
|
|
|
|
declare void @llvm.memset.p0.i32(ptr writeonly captures(none), i8, i32, i1 immarg)
|