These involved regenerating test checks. There are two significant differences here: 1. With typed pointers we sometimes swapped gep and addrspacecast, as a side-effect of other transforms. However, the current direction is likely undesirable, and we should canonicalize in the reverse direction instead (gep of ac, instead of ac of gep). This should be done after typed pointers are removed, to avoid conflicting transforms. 2. The "descaling" optimization isn't really compatible with opaque pointers. This will be addressed longer-term by moving away from type-based GEP, at which point the form with explicit multiplications will be the canonical one.
78 lines
3.3 KiB
LLVM
78 lines
3.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
target triple = "x86_64-pc-win32"
|
|
|
|
%myStruct = type { float, [3 x float], [4 x float], i32 }
|
|
|
|
; make sure that we are not crashing when creating an illegal type
|
|
define void @func(ptr addrspace(1) nocapture %p) nounwind {
|
|
; CHECK-LABEL: @func(
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%B = addrspacecast ptr addrspace(1) %p to ptr
|
|
%C = getelementptr inbounds %myStruct, ptr %B, i32 0, i32 1
|
|
%D = getelementptr inbounds [3 x float], ptr %C, i32 0, i32 2
|
|
%E = load float, ptr %D, align 4
|
|
%F = fsub float %E, undef
|
|
ret void
|
|
}
|
|
|
|
@array = internal addrspace(3) global [256 x float] zeroinitializer, align 4
|
|
@scalar = internal addrspace(3) global float 0.000000e+00, align 4
|
|
|
|
define void @keep_necessary_addrspacecast(i64 %i, ptr %out0, ptr %out1) {
|
|
; CHECK-LABEL: @keep_necessary_addrspacecast(
|
|
; CHECK-NEXT: [[T0:%.*]] = getelementptr [256 x float], ptr addrspacecast (ptr addrspace(3) @array to ptr), i64 0, i64 [[I:%.*]]
|
|
; CHECK-NEXT: [[T1:%.*]] = getelementptr [0 x float], ptr addrspacecast (ptr addrspace(3) @scalar to ptr), i64 0, i64 [[I]]
|
|
; CHECK-NEXT: store ptr [[T0]], ptr [[OUT0:%.*]], align 4
|
|
; CHECK-NEXT: store ptr [[T1]], ptr [[OUT1:%.*]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%t0 = getelementptr [256 x float], ptr addrspacecast (ptr addrspace(3) @array to ptr), i64 0, i64 %i
|
|
%t1 = getelementptr [0 x float], ptr addrspacecast (ptr addrspace(3) @scalar to ptr), i64 0, i64 %i
|
|
store ptr %t0, ptr %out0, align 4
|
|
store ptr %t1, ptr %out1, align 4
|
|
ret void
|
|
}
|
|
|
|
declare void @escape_alloca(ptr)
|
|
|
|
; check that addrspacecast is stripped when trying to mark a GEP as inbounds
|
|
define { i8, i8 } @inbounds_after_addrspacecast() {
|
|
; CHECK-LABEL: @inbounds_after_addrspacecast(
|
|
; CHECK-NEXT: [[T0:%.*]] = alloca i16, align 2
|
|
; CHECK-NEXT: call void @escape_alloca(ptr nonnull [[T0]])
|
|
; CHECK-NEXT: [[T1:%.*]] = addrspacecast ptr [[T0]] to ptr addrspace(11)
|
|
; CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [2 x i8], ptr addrspace(11) [[T1]], i64 0, i64 1
|
|
; CHECK-NEXT: [[T3:%.*]] = load i8, ptr addrspace(11) [[T2]], align 1
|
|
; CHECK-NEXT: [[INSERT:%.*]] = insertvalue { i8, i8 } zeroinitializer, i8 [[T3]], 1
|
|
; CHECK-NEXT: ret { i8, i8 } [[INSERT]]
|
|
;
|
|
%t0 = alloca i16, align 2
|
|
call void @escape_alloca(ptr %t0)
|
|
%t1 = addrspacecast ptr %t0 to ptr addrspace(11)
|
|
%t2 = getelementptr [2 x i8], ptr addrspace(11) %t1, i64 0, i64 1
|
|
%t3 = load i8, ptr addrspace(11) %t2, align 1
|
|
%insert = insertvalue { i8, i8 } zeroinitializer, i8 %t3, 1
|
|
ret { i8, i8 } %insert
|
|
}
|
|
|
|
|
|
declare spir_func <16 x i32> @my_extern_func()
|
|
|
|
; check that a bitcast is not generated when we need an addrspace cast
|
|
define void @bitcast_after_gep(ptr %t0) {
|
|
; CHECK-LABEL: @bitcast_after_gep(
|
|
; CHECK-NEXT: [[T2:%.*]] = addrspacecast ptr [[T0:%.*]] to ptr addrspace(3)
|
|
; CHECK-NEXT: [[CALL:%.*]] = call spir_func <16 x i32> @my_extern_func()
|
|
; CHECK-NEXT: store <16 x i32> [[CALL]], ptr addrspace(3) [[T2]], align 64
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%t2 = addrspacecast ptr %t0 to ptr addrspace(3)
|
|
%call = call spir_func <16 x i32> @my_extern_func()
|
|
store <16 x i32> %call, ptr addrspace(3) %t2
|
|
ret void
|
|
}
|