This was looking through an addrspacecast, and not finding a later
unfoldable cast to another address space. Fixes improperly deleting
a required alloca + memcpy and introducing an illegal addrspacecast.
This also required fixing some worklist management issues with
addrspacecast, and assuming that only memcpy sources could need
replacement.
Regresses one test function, but this looks like it optimized
before by accident. It never saw the pointer use by the call
to readonly_callee, which should require insertion of a new cast.
Fixes #68120
82 lines
4.9 KiB
LLVM
82 lines
4.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine %s | FileCheck %s
|
|
|
|
; It is illegal to pass ptr addrspace(4) in %arg by addrspacecasting
|
|
; to ptr addrspace(5) to pass off to the stack argument. A temporary
|
|
; alloca and memcpy is necessary.
|
|
define void @issue68120_invalid_addrspacecast_introduced_0(ptr addrspace(4) byref([56 x i8]) %arg) {
|
|
; CHECK-LABEL: define void @issue68120_invalid_addrspacecast_introduced_0(
|
|
; CHECK-SAME: ptr addrspace(4) byref([56 x i8]) [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[ADDRSPACECAST_0_TO_5:%.*]] = alloca [56 x i8], align 1, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 1 dereferenceable(56) [[ADDRSPACECAST_0_TO_5]], ptr addrspace(4) noundef align 1 dereferenceable(56) [[ARG]], i64 56, i1 false)
|
|
; CHECK-NEXT: call void @byval_func(ptr addrspace(5) [[ADDRSPACECAST_0_TO_5]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%alloca = alloca [56 x i8], addrspace(5)
|
|
%alloca1 = alloca [56 x i8], addrspace(5)
|
|
call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 56, i1 false)
|
|
call void @llvm.memcpy.p5.p5.i64(ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca, i64 56, i1 false)
|
|
%addrspacecast.alloca1 = addrspacecast ptr addrspace(5) %alloca1 to ptr
|
|
%addrspacecast.0.to.5 = addrspacecast ptr %addrspacecast.alloca1 to ptr addrspace(5)
|
|
call void @byval_func(ptr addrspace(5) %addrspacecast.0.to.5)
|
|
ret void
|
|
}
|
|
|
|
; Further reduced variant that already eliminated one of the copies
|
|
define void @issue68120_invalid_addrspacecast_introduced_1(ptr addrspace(4) byref([56 x i8]) %arg) {
|
|
; CHECK-LABEL: define void @issue68120_invalid_addrspacecast_introduced_1(
|
|
; CHECK-SAME: ptr addrspace(4) byref([56 x i8]) [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[ADDRSPACECAST_0_TO_5:%.*]] = alloca [56 x i8], align 1, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 1 dereferenceable(56) [[ADDRSPACECAST_0_TO_5]], ptr addrspace(4) noundef align 1 dereferenceable(56) [[ARG]], i64 56, i1 false)
|
|
; CHECK-NEXT: call void @byval_func(ptr addrspace(5) [[ADDRSPACECAST_0_TO_5]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%alloca = alloca [56 x i8], addrspace(5)
|
|
call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 56, i1 false)
|
|
%addrspacecast.alloca = addrspacecast ptr addrspace(5) %alloca to ptr
|
|
%addrspacecast.0.to.5 = addrspacecast ptr %addrspacecast.alloca to ptr addrspace(5)
|
|
call void @byval_func(ptr addrspace(5) %addrspacecast.0.to.5)
|
|
ret void
|
|
}
|
|
|
|
define void @issue68120_use_cast_to_as0(ptr addrspace(4) byref([56 x i8]) %arg) {
|
|
; CHECK-LABEL: define void @issue68120_use_cast_to_as0(
|
|
; CHECK-SAME: ptr addrspace(4) byref([56 x i8]) [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [56 x i8], align 1, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 1 dereferenceable(56) [[ALLOCA]], ptr addrspace(4) noundef align 1 dereferenceable(56) [[ARG]], i64 56, i1 false)
|
|
; CHECK-NEXT: [[ADDRSPACECAST_ALLOCA:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
|
|
; CHECK-NEXT: call void @other_func(ptr [[ADDRSPACECAST_ALLOCA]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%alloca = alloca [56 x i8], addrspace(5)
|
|
call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %alloca, ptr addrspace(4) %arg, i64 56, i1 false)
|
|
%addrspacecast.alloca = addrspacecast ptr addrspace(5) %alloca to ptr
|
|
%addrspacecast.0.to.5 = addrspacecast ptr %addrspacecast.alloca to ptr addrspace(5)
|
|
call void @other_func(ptr %addrspacecast.alloca)
|
|
ret void
|
|
}
|
|
|
|
define void @issue68120_uses_invalid_addrspacecast(ptr addrspace(4) byref([56 x i8]) %arg) {
|
|
; CHECK-LABEL: define void @issue68120_uses_invalid_addrspacecast(
|
|
; CHECK-SAME: ptr addrspace(4) byref([56 x i8]) [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[ADDRSPACECAST_0_TO_5:%.*]] = alloca [56 x i8], align 1, addrspace(5)
|
|
; CHECK-NEXT: call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) noundef align 1 dereferenceable(56) [[ADDRSPACECAST_0_TO_5]], ptr addrspace(4) noundef align 1 dereferenceable(56) [[ARG]], i64 56, i1 false)
|
|
; CHECK-NEXT: call void @byval_func(ptr addrspace(5) [[ADDRSPACECAST_0_TO_5]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%alloca = alloca [56 x i8], addrspace(5)
|
|
%alloca1 = alloca [56 x i8], addrspace(5)
|
|
%illegal.cast = addrspacecast ptr addrspace(4) %arg to ptr addrspace(5)
|
|
call void @llvm.memcpy.p5.p5.i64(ptr addrspace(5) %alloca, ptr addrspace(5) %illegal.cast, i64 56, i1 false)
|
|
call void @llvm.memcpy.p5.p5.i64(ptr addrspace(5) %alloca1, ptr addrspace(5) %alloca, i64 56, i1 false)
|
|
%addrspacecast.alloca1 = addrspacecast ptr addrspace(5) %alloca1 to ptr
|
|
%addrspacecast.0.to.5 = addrspacecast ptr %addrspacecast.alloca1 to ptr addrspace(5)
|
|
call void @byval_func(ptr addrspace(5) %addrspacecast.0.to.5)
|
|
ret void
|
|
}
|
|
|
|
|
|
declare void @byval_func(ptr addrspace(5) byval([56 x i8]))
|
|
declare void @other_func(ptr)
|
|
|