; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt < %s -passes=nvptx-set-byval-param-align -S | FileCheck %s target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" target triple = "nvptx64-nvidia-cuda" %struct.S = type { i32, i32 } ; Kernel byval with no alignment: should get ABI align of i32 (4). define ptx_kernel void @kernel_no_align(ptr byval(i32) %s) { ; CHECK-LABEL: define ptx_kernel void @kernel_no_align( ; CHECK-SAME: ptr byval(i32) align 4 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Kernel byval with low alignment: should be bumped to ABI align (4). define ptx_kernel void @kernel_low_align(ptr byval(%struct.S) align 1 %s) { ; CHECK-LABEL: define ptx_kernel void @kernel_low_align( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 4 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Kernel byval with adequate alignment: should stay unchanged. define ptx_kernel void @kernel_high_align(ptr byval(%struct.S) align 8 %s) { ; CHECK-LABEL: define ptx_kernel void @kernel_high_align( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 8 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; External device function: gets ABI alignment (4). define void @device_extern_no_align(ptr byval(%struct.S) %s) { ; CHECK-LABEL: define void @device_extern_no_align( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 4 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Internal device function: gets max(16, ABI) = 16. define internal void @device_internal_no_align(ptr byval(%struct.S) %s) { ; CHECK-LABEL: define internal void @device_internal_no_align( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 16 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Internal device function with adequate alignment: stays unchanged. define internal void @device_internal_high_align(ptr byval(%struct.S) align 32 %s) { ; CHECK-LABEL: define internal void @device_internal_high_align( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 32 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Large vector type: ABI alignment exceeds 128 bytes, capped to PTX maximum. define ptx_kernel void @kernel_align_cap(ptr byval(<256 x i32>) %s) { ; CHECK-LABEL: define ptx_kernel void @kernel_align_cap( ; CHECK-SAME: ptr byval(<256 x i32>) align 128 [[S:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Non-byval args should be untouched. define ptx_kernel void @no_byval(ptr %p, i32 %x) { ; CHECK-LABEL: define ptx_kernel void @no_byval( ; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) { ; CHECK-NEXT: ret void ; ret void } ; Load propagation: loads at known offsets get alignment upgraded. define ptx_kernel void @load_propagation(ptr byval(%struct.S) %s) { ; CHECK-LABEL: define ptx_kernel void @load_propagation( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 4 [[S:%.*]]) { ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[S]], align 4 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP]], align 4 ; CHECK-NEXT: ret void ; %v1 = load i32, ptr %s, align 1 %gep = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 %v2 = load i32, ptr %gep, align 1 ret void } ; Load propagation through bitcast. define ptx_kernel void @load_through_bitcast(ptr byval(%struct.S) %s) { ; CHECK-LABEL: define ptx_kernel void @load_through_bitcast( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 4 [[S:%.*]]) { ; CHECK-NEXT: [[V1:%.*]] = load i64, ptr [[S]], align 4 ; CHECK-NEXT: ret void ; %v1 = load i64, ptr %s, align 1 ret void } ; Internal function gets higher alignment, which propagates to loads. define internal void @internal_load_propagation(ptr byval(%struct.S) %s) { ; CHECK-LABEL: define internal void @internal_load_propagation( ; CHECK-SAME: ptr byval([[STRUCT_S:%.*]]) align 16 [[S:%.*]]) { ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[S]], align 16 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1 ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[GEP]], align 4 ; CHECK-NEXT: ret void ; %v1 = load i32, ptr %s, align 1 %gep = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1 %v2 = load i32, ptr %gep, align 1 ret void }