; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -S -passes=instcombine < %s | FileCheck %s
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
target triple = "i386-apple-darwin10.0.0"
; CHECK-SAME: (i32 [[PARM:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[PTR:%.*]] = alloca double*, align 4
-; CHECK-NEXT: store i32 [[PARM]], i32* [[I]], align 4
-; CHECK-NEXT: store double* null, double** [[PTR]], align 4
+; CHECK-NEXT: [[PTR:%.*]] = alloca ptr, align 4
+; CHECK-NEXT: store i32 [[PARM]], ptr [[I]], align 4
+; CHECK-NEXT: store ptr null, ptr [[PTR]], align 4
; CHECK-NEXT: [[I2_NOT:%.*]] = icmp eq i32 [[PARM]], 0
; CHECK-NEXT: br i1 [[I2_NOT]], label [[BB9:%.*]], label [[BB3:%.*]]
; CHECK: bb3:
-; CHECK-NEXT: [[I4:%.*]] = load i32, i32* [[I]], align 4
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[I4]], 256
-; CHECK-NEXT: [[I7:%.*]] = alloca double, i32 [[TMP0]], align 1
-; CHECK-NEXT: store double* [[I7]], double** [[PTR]], align 4
+; CHECK-NEXT: [[I4:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[I5:%.*]] = shl nuw i32 [[I4]], 3
+; CHECK-NEXT: [[I6:%.*]] = add nuw i32 [[I5]], 2048
+; CHECK-NEXT: [[I7:%.*]] = alloca i8, i32 [[I6]], align 1
+; CHECK-NEXT: store ptr [[I7]], ptr [[PTR]], align 4
; CHECK-NEXT: br label [[BB9]]
; CHECK: bb9:
-; CHECK-NEXT: [[I10:%.*]] = load double*, double** [[PTR]], align 4
-; CHECK-NEXT: call void @bar(double* [[I10]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[I10:%.*]] = load ptr, ptr [[PTR]], align 4
+; CHECK-NEXT: call void @bar(ptr [[I10]]) #[[ATTR1:[0-9]+]]
; CHECK-NEXT: ret void
;
bb:
%i = alloca i32, align 4
- %ptr = alloca double*, align 4
- store i32 %parm, i32* %i, align 4
- store double* null, double** %ptr, align 4
- %i1 = load i32, i32* %i, align 4
+ %ptr = alloca ptr, align 4
+ store i32 %parm, ptr %i, align 4
+ store ptr null, ptr %ptr, align 4
+ %i1 = load i32, ptr %i, align 4
%i2 = icmp ne i32 %i1, 0
br i1 %i2, label %bb3, label %bb9
bb3: ; preds = %bb
- %i4 = load i32, i32* %i, align 4
+ %i4 = load i32, ptr %i, align 4
%i5 = shl nuw i32 %i4, 3
; With "nuw", the alloca and its bitcast can be fused:
%i6 = add nuw i32 %i5, 2048
%i7 = alloca i8, i32 %i6, align 1
- %i8 = bitcast i8* %i7 to double*
- store double* %i8, double** %ptr, align 4
+ store ptr %i7, ptr %ptr, align 4
br label %bb9
bb9: ; preds = %bb3, %bb
- %i10 = load double*, double** %ptr, align 4
- call void @bar(double* %i10)
+ %i10 = load ptr, ptr %ptr, align 4
+ call void @bar(ptr %i10)
ret void
}
-declare void @bar(double*)
+declare void @bar(ptr)
define void @fu2(i32 %parm) #0 {
; CHECK-LABEL: define void @fu2
; CHECK-SAME: (i32 [[PARM:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[PTR:%.*]] = alloca double*, align 4
-; CHECK-NEXT: store i32 [[PARM]], i32* [[I]], align 4
-; CHECK-NEXT: store double* null, double** [[PTR]], align 4
+; CHECK-NEXT: [[PTR:%.*]] = alloca ptr, align 4
+; CHECK-NEXT: store i32 [[PARM]], ptr [[I]], align 4
+; CHECK-NEXT: store ptr null, ptr [[PTR]], align 4
; CHECK-NEXT: [[I2_NOT:%.*]] = icmp eq i32 [[PARM]], 0
; CHECK-NEXT: br i1 [[I2_NOT]], label [[BB9:%.*]], label [[BB3:%.*]]
; CHECK: bb3:
-; CHECK-NEXT: [[I4:%.*]] = load i32, i32* [[I]], align 4
+; CHECK-NEXT: [[I4:%.*]] = load i32, ptr [[I]], align 4
; CHECK-NEXT: [[I5:%.*]] = shl nuw i32 [[I4]], 3
; CHECK-NEXT: [[I6:%.*]] = add i32 [[I5]], 2048
; CHECK-NEXT: [[I7:%.*]] = alloca i8, i32 [[I6]], align 1
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast double** [[PTR]] to i8**
-; CHECK-NEXT: store i8* [[I7]], i8** [[TMP0]], align 4
+; CHECK-NEXT: store ptr [[I7]], ptr [[PTR]], align 4
; CHECK-NEXT: br label [[BB9]]
; CHECK: bb9:
-; CHECK-NEXT: [[I10:%.*]] = load double*, double** [[PTR]], align 4
-; CHECK-NEXT: call void @bar(double* [[I10]]) #[[ATTR1]]
+; CHECK-NEXT: [[I10:%.*]] = load ptr, ptr [[PTR]], align 4
+; CHECK-NEXT: call void @bar(ptr [[I10]]) #[[ATTR1]]
; CHECK-NEXT: ret void
;
bb:
%i = alloca i32, align 4
- %ptr = alloca double*, align 4
- store i32 %parm, i32* %i, align 4
- store double* null, double** %ptr, align 4
- %i1 = load i32, i32* %i, align 4
+ %ptr = alloca ptr, align 4
+ store i32 %parm, ptr %i, align 4
+ store ptr null, ptr %ptr, align 4
+ %i1 = load i32, ptr %i, align 4
%i2 = icmp ne i32 %i1, 0
br i1 %i2, label %bb3, label %bb9
bb3: ; preds = %bb
- %i4 = load i32, i32* %i, align 4
+ %i4 = load i32, ptr %i, align 4
%i5 = mul nuw i32 %i4, 8
; Without "nuw", the alloca and its bitcast cannot be fused:
%i6 = add i32 %i5, 2048
%i7 = alloca i8, i32 %i6, align 1
- %i8 = bitcast i8* %i7 to double*
- store double* %i8, double** %ptr, align 4
+ store ptr %i7, ptr %ptr, align 4
br label %bb9
bb9: ; preds = %bb3, %bb
- %i10 = load double*, double** %ptr, align 4
- call void @bar(double* %i10)
+ %i10 = load ptr, ptr %ptr, align 4
+ call void @bar(ptr %i10)
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -passes=instcombine -S < %s | FileCheck %s
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
-declare void @llvm.init.trampoline(i8*, i8*, i8*)
-declare i8* @llvm.adjust.trampoline(i8*)
-declare i32 @f(i8 * nest, i32)
+declare void @llvm.init.trampoline(ptr, ptr, ptr)
+declare ptr @llvm.adjust.trampoline(ptr)
+declare i32 @f(ptr nest, i32)
; Most common case
define i32 @test0(i32 %n) !dbg !4 {
; CHECK-LABEL: define i32 @test0
; CHECK-SAME: (i32 [[N:%.*]]) !dbg [[DBG4:![0-9]+]] {
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [10 x i8], align 16
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* [[ALLOCA]], i64 0, i64 0
-; CHECK-NEXT: call void @llvm.init.trampoline(i8* nonnull [[GEP]], i8* nonnull bitcast (i32 (i8*, i32)* @f to i8*), i8* null)
-; CHECK-NEXT: [[RET:%.*]] = call i32 @f(i8* nest null, i32 [[N]]), !dbg [[DBG10:![0-9]+]]
+; CHECK-NEXT: call void @llvm.init.trampoline(ptr nonnull [[ALLOCA]], ptr nonnull @f, ptr null)
+; CHECK-NEXT: [[RET:%.*]] = call i32 @f(ptr nest null, i32 [[N]]), !dbg [[DBG10:![0-9]+]]
; CHECK-NEXT: ret i32 [[RET]]
;
%alloca = alloca [10 x i8], align 16
- %gep = getelementptr [10 x i8], [10 x i8]* %alloca, i32 0, i32 0
- call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
- i8* null)
- %tramp = call i8* @llvm.adjust.trampoline(i8* %gep)
- %function = bitcast i8* %tramp to i32(i32)*
- %ret = call i32 %function(i32 %n), !dbg !10
+ call void @llvm.init.trampoline(ptr %alloca, ptr @f,
+ ptr null)
+ %tramp = call ptr @llvm.adjust.trampoline(ptr %alloca)
+ %ret = call i32 %tramp(i32 %n), !dbg !10
ret i32 %ret
}
-define i32 @test1(i32 %n, i8* %trampmem) {
+define i32 @test1(i32 %n, ptr %trampmem) {
; CHECK-LABEL: define i32 @test1
-; CHECK-SAME: (i32 [[N:%.*]], i8* [[TRAMPMEM:%.*]]) {
-; CHECK-NEXT: call void @llvm.init.trampoline(i8* [[TRAMPMEM]], i8* nonnull bitcast (i32 (i8*, i32)* @f to i8*), i8* null)
-; CHECK-NEXT: [[RET:%.*]] = call i32 @f(i8* nest null, i32 [[N]])
+; CHECK-SAME: (i32 [[N:%.*]], ptr [[TRAMPMEM:%.*]]) {
+; CHECK-NEXT: call void @llvm.init.trampoline(ptr [[TRAMPMEM]], ptr nonnull @f, ptr null)
+; CHECK-NEXT: [[RET:%.*]] = call i32 @f(ptr nest null, i32 [[N]])
; CHECK-NEXT: ret i32 [[RET]]
;
- call void @llvm.init.trampoline(i8* %trampmem,
- i8* bitcast (i32 (i8*, i32)* @f to i8*),
- i8* null)
- %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
- %function = bitcast i8* %tramp to i32(i32)*
- %ret = call i32 %function(i32 %n)
+ call void @llvm.init.trampoline(ptr %trampmem,
+ ptr @f,
+ ptr null)
+ %tramp = call ptr @llvm.adjust.trampoline(ptr %trampmem)
+ %ret = call i32 %tramp(i32 %n)
ret i32 %ret
}
-define i32 @test2(i32 %n, i8* %trampmem) {
+define i32 @test2(i32 %n, ptr %trampmem) {
; CHECK-LABEL: define i32 @test2
-; CHECK-SAME: (i32 [[N:%.*]], i8* [[TRAMPMEM:%.*]]) {
-; CHECK-NEXT: [[TRAMP:%.*]] = call i8* @llvm.adjust.trampoline(i8* [[TRAMPMEM]])
-; CHECK-NEXT: [[FUNCTIONA:%.*]] = bitcast i8* [[TRAMP]] to i32 (i32)*
-; CHECK-NEXT: [[RET:%.*]] = call i32 [[FUNCTIONA]](i32 [[N]])
+; CHECK-SAME: (i32 [[N:%.*]], ptr [[TRAMPMEM:%.*]]) {
+; CHECK-NEXT: [[TRAMP:%.*]] = call ptr @llvm.adjust.trampoline(ptr [[TRAMPMEM]])
+; CHECK-NEXT: [[RET:%.*]] = call i32 [[TRAMP]](i32 [[N]])
; CHECK-NEXT: ret i32 [[RET]]
;
- %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem)
- %functiona = bitcast i8* %tramp to i32(i32)*
- %ret = call i32 %functiona(i32 %n)
+ %tramp = call ptr @llvm.adjust.trampoline(ptr %trampmem)
+ %ret = call i32 %tramp(i32 %n)
ret i32 %ret
}
-define i32 @test3(i32 %n, i8* %trampmem) {
+define i32 @test3(i32 %n, ptr %trampmem) {
; CHECK-LABEL: define i32 @test3
-; CHECK-SAME: (i32 [[N:%.*]], i8* [[TRAMPMEM:%.*]]) {
-; CHECK-NEXT: call void @llvm.init.trampoline(i8* [[TRAMPMEM]], i8* nonnull bitcast (i32 (i8*, i32)* @f to i8*), i8* null)
-; CHECK-NEXT: [[RET0:%.*]] = call i32 @f(i8* nest null, i32 [[N]])
-; CHECK-NEXT: [[TRAMP1:%.*]] = call i8* @llvm.adjust.trampoline(i8* [[TRAMPMEM]])
-; CHECK-NEXT: [[FUNCTION1:%.*]] = bitcast i8* [[TRAMP1]] to i32 (i32)*
-; CHECK-NEXT: [[RET1:%.*]] = call i32 [[FUNCTION1]](i32 [[N]])
+; CHECK-SAME: (i32 [[N:%.*]], ptr [[TRAMPMEM:%.*]]) {
+; CHECK-NEXT: call void @llvm.init.trampoline(ptr [[TRAMPMEM]], ptr nonnull @f, ptr null)
+; CHECK-NEXT: [[RET0:%.*]] = call i32 @f(ptr nest null, i32 [[N]])
+; CHECK-NEXT: [[TRAMP1:%.*]] = call ptr @llvm.adjust.trampoline(ptr [[TRAMPMEM]])
+; CHECK-NEXT: [[RET1:%.*]] = call i32 [[TRAMP1]](i32 [[N]])
; CHECK-NEXT: ret i32 [[RET1]]
;
- call void @llvm.init.trampoline(i8* %trampmem,
- i8* bitcast (i32 (i8*, i32)* @f to i8*),
- i8* null)
+ call void @llvm.init.trampoline(ptr %trampmem,
+ ptr @f,
+ ptr null)
- %tramp0 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
- %function0 = bitcast i8* %tramp0 to i32(i32)*
- %ret0 = call i32 %function0(i32 %n)
+ %tramp0 = call ptr @llvm.adjust.trampoline(ptr %trampmem)
+ %ret0 = call i32 %tramp0(i32 %n)
;; Not optimized since previous call could be writing.
- %tramp1 = call i8* @llvm.adjust.trampoline(i8* %trampmem)
- %function1 = bitcast i8* %tramp1 to i32(i32)*
- %ret1 = call i32 %function1(i32 %n)
+ %tramp1 = call ptr @llvm.adjust.trampoline(ptr %trampmem)
+ %ret1 = call i32 %tramp1(i32 %n)
ret i32 %ret1
}
; CHECK-LABEL: define i32 @test4
; CHECK-SAME: (i32 [[N:%.*]]) {
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [10 x i8], align 16
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* [[ALLOCA]], i64 0, i64 0
-; CHECK-NEXT: call void @llvm.init.trampoline(i8* nonnull [[GEP]], i8* nonnull bitcast (i32 (i8*, i32)* @f to i8*), i8* null)
-; CHECK-NEXT: [[RET0:%.*]] = call i32 @f(i8* nest null, i32 [[N]])
-; CHECK-NEXT: [[RET1:%.*]] = call i32 @f(i8* nest null, i32 [[N]])
-; CHECK-NEXT: [[RET2:%.*]] = call i32 @f(i8* nest null, i32 [[N]])
+; CHECK-NEXT: call void @llvm.init.trampoline(ptr nonnull [[ALLOCA]], ptr nonnull @f, ptr null)
+; CHECK-NEXT: [[RET0:%.*]] = call i32 @f(ptr nest null, i32 [[N]])
+; CHECK-NEXT: [[RET1:%.*]] = call i32 @f(ptr nest null, i32 [[N]])
+; CHECK-NEXT: [[RET2:%.*]] = call i32 @f(ptr nest null, i32 [[N]])
; CHECK-NEXT: ret i32 [[RET2]]
;
%alloca = alloca [10 x i8], align 16
- %gep = getelementptr [10 x i8], [10 x i8]* %alloca, i32 0, i32 0
- call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*),
- i8* null)
+ call void @llvm.init.trampoline(ptr %alloca, ptr @f,
+ ptr null)
- %tramp0 = call i8* @llvm.adjust.trampoline(i8* %gep)
- %function0 = bitcast i8* %tramp0 to i32(i32)*
- %ret0 = call i32 %function0(i32 %n)
+ %tramp0 = call ptr @llvm.adjust.trampoline(ptr %alloca)
+ %ret0 = call i32 %tramp0(i32 %n)
- %tramp1 = call i8* @llvm.adjust.trampoline(i8* %gep)
- %function1 = bitcast i8* %tramp0 to i32(i32)*
- %ret1 = call i32 %function1(i32 %n)
+ %tramp1 = call ptr @llvm.adjust.trampoline(ptr %alloca)
+ %ret1 = call i32 %tramp0(i32 %n)
- %tramp2 = call i8* @llvm.adjust.trampoline(i8* %gep)
- %function2 = bitcast i8* %tramp2 to i32(i32)*
- %ret2 = call i32 %function2(i32 %n)
+ %tramp2 = call ptr @llvm.adjust.trampoline(ptr %alloca)
+ %ret2 = call i32 %tramp2(i32 %n)
ret i32 %ret2
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -S -passes=instcombine < %s | FileCheck %s
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
; rdar://problem/10063307
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
target triple = "thumbv7-apple-ios5.0.0"
%0 = type { [2 x i32] }
%struct.CGPoint = type { float, float }
-define void @t(%struct.CGPoint* %a) nounwind {
+define void @t(ptr %a) nounwind {
; CHECK-LABEL: define void @t
-; CHECK-SAME: (%struct.CGPoint* [[A:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[POINT:%.*]] = alloca i64, align 4
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.CGPoint* [[A]] to i64*
-; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 4
-; CHECK-NEXT: store i64 [[TMP2]], i64* [[POINT]], align 4
-; CHECK-NEXT: call void @foo(i64* nonnull [[POINT]]) #[[ATTR0]]
+; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[POINT:%.*]] = alloca [[STRUCT_CGPOINT:%.*]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[A]], align 4
+; CHECK-NEXT: store i64 [[TMP1]], ptr [[POINT]], align 4
+; CHECK-NEXT: call void @foo(ptr nonnull [[POINT]]) #[[ATTR0]]
; CHECK-NEXT: ret void
;
%Point = alloca %struct.CGPoint, align 4
- %1 = bitcast %struct.CGPoint* %a to i64*
- %2 = bitcast %struct.CGPoint* %Point to i64*
- %3 = load i64, i64* %1, align 4
- store i64 %3, i64* %2, align 4
- call void @foo(i64* %2) nounwind
+ %1 = load i64, ptr %a, align 4
+ store i64 %1, ptr %Point, align 4
+ call void @foo(ptr %Point) nounwind
ret void
}
-declare void @foo(i64*)
+declare void @foo(ptr)
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -S -passes=instcombine -o - %s | FileCheck %s
+; RUN: opt -S -passes=instcombine -o - %s | FileCheck %s
target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v64:64:64-v128:128:128-a0:0:64"
define internal <2 x i32> @func_v2i32(<2 x i32> %v) noinline nounwind {
ret <2 x i64> %v
}
-define internal <2 x i32*> @func_v2i32p(<2 x i32*> %v) noinline nounwind {
-; CHECK-LABEL: define internal <2 x i32*> @func_v2i32p
-; CHECK-SAME: (<2 x i32*> [[V:%.*]]) #[[ATTR0]] {
+define internal <2 x ptr> @func_v2i32p(<2 x ptr> %v) noinline nounwind {
+; CHECK-LABEL: define internal <2 x ptr> @func_v2i32p
+; CHECK-SAME: (<2 x ptr> [[V:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: ret <2 x i32*> [[V]]
+; CHECK-NEXT: ret <2 x ptr> [[V]]
;
entry:
- ret <2 x i32*> %v
+ ret <2 x ptr> %v
}
; Valid cases, only bitcast for argument / return type and call underlying function
; Test cast between scalars with same bit sizes
; Sizes match, should only bitcast
-define void @bitcast_scalar(float* noalias %source, float* noalias %dest) nounwind {
+define void @bitcast_scalar(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_scalar
-; CHECK-SAME: (float* noalias [[SOURCE:%.*]], float* noalias [[DEST:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[SOURCE]] to i32*
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[SOURCE]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call i32 @func_i32(i32 [[TMP1]]) #[[ATTR1]]
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[DEST]] to i32*
-; CHECK-NEXT: store i32 [[CALL]], i32* [[TMP1]], align 8
+; CHECK-NEXT: store i32 [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load float, float* %source, align 8
- %call = call float bitcast (i32 (i32)* @func_i32 to float (float)*)(float %tmp) nounwind
- store float %call, float* %dest, align 8
+ %tmp = load float, ptr %source, align 8
+ %call = call float @func_i32(float %tmp) nounwind
+ store float %call, ptr %dest, align 8
ret void
}
; Test cast between vectors with same number of elements and bit sizes
; Sizes match, should only bitcast
-define void @bitcast_vector(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
+define void @bitcast_vector(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector
-; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float>* [[SOURCE]] to <2 x i32>*
-; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, <2 x i32>* [[TMP0]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[SOURCE]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call <2 x i32> @func_v2i32(<2 x i32> [[TMP1]]) #[[ATTR1]]
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float>* [[DEST]] to <2 x i32>*
-; CHECK-NEXT: store <2 x i32> [[CALL]], <2 x i32>* [[TMP1]], align 8
+; CHECK-NEXT: store <2 x i32> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <2 x float>, <2 x float>* %source, align 8
- %call = call <2 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind
- store <2 x float> %call, <2 x float>* %dest, align 8
+ %tmp = load <2 x float>, ptr %source, align 8
+ %call = call <2 x float> @func_v2i32(<2 x float> %tmp) nounwind
+ store <2 x float> %call, ptr %dest, align 8
ret void
}
; Test cast from vector to scalar with same number of bits
; Sizes match, should only bitcast
-define void @bitcast_vector_scalar_same_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
+define void @bitcast_vector_scalar_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector_scalar_same_size
-; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float>* [[SOURCE]] to i64*
-; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[SOURCE]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call i64 @func_i64(i64 [[TMP1]]) #[[ATTR1]]
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float>* [[DEST]] to i64*
-; CHECK-NEXT: store i64 [[CALL]], i64* [[TMP1]], align 8
+; CHECK-NEXT: store i64 [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <2 x float>, <2 x float>* %source, align 8
- %call = call <2 x float> bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind
- store <2 x float> %call, <2 x float>* %dest, align 8
+ %tmp = load <2 x float>, ptr %source, align 8
+ %call = call <2 x float> @func_i64(<2 x float> %tmp) nounwind
+ store <2 x float> %call, ptr %dest, align 8
ret void
}
; Test cast from scalar to vector with same number of bits
-define void @bitcast_scalar_vector_same_size(i64* noalias %source, i64* noalias %dest) nounwind {
+define void @bitcast_scalar_vector_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_scalar_vector_same_size
-; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[SOURCE]] to <2 x float>*
-; CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, <2 x float>* [[TMP0]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[SOURCE]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @func_v2f32(<2 x float> [[TMP1]]) #[[ATTR1]]
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[DEST]] to <2 x float>*
-; CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[TMP1]], align 8
+; CHECK-NEXT: store <2 x float> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load i64, i64* %source, align 8
- %call = call i64 bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*)(i64 %tmp) nounwind
- store i64 %call, i64* %dest, align 8
+ %tmp = load i64, ptr %source, align 8
+ %call = call i64 @func_v2f32(i64 %tmp) nounwind
+ store i64 %call, ptr %dest, align 8
ret void
}
; Test cast between vectors of pointers
-define void @bitcast_vector_ptrs_same_size(<2 x i64*>* noalias %source, <2 x i64*>* noalias %dest) nounwind {
+define void @bitcast_vector_ptrs_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector_ptrs_same_size
-; CHECK-SAME: (<2 x i64*>* noalias [[SOURCE:%.*]], <2 x i64*>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64*>* [[SOURCE]] to <2 x i32*>*
-; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32*>, <2 x i32*>* [[TMP0]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call <2 x i32*> @func_v2i32p(<2 x i32*> [[TMP1]]) #[[ATTR1]]
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64*>* [[DEST]] to <2 x i32*>*
-; CHECK-NEXT: store <2 x i32*> [[CALL]], <2 x i32*>* [[TMP1]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x ptr>, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call <2 x ptr> @func_v2i32p(<2 x ptr> [[TMP1]]) #[[ATTR1]]
+; CHECK-NEXT: store <2 x ptr> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <2 x i64*>, <2 x i64*>* %source, align 8
- %call = call <2 x i64*> bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*)(<2 x i64*> %tmp) nounwind
- store <2 x i64*> %call, <2 x i64*>* %dest, align 8
+ %tmp = load <2 x ptr>, ptr %source, align 8
+ %call = call <2 x ptr> @func_v2i32p(<2 x ptr> %tmp) nounwind
+ store <2 x ptr> %call, ptr %dest, align 8
ret void
}
; Invalid cases:
; Test cast between scalars with different bit sizes
-define void @bitcast_mismatch_scalar_size(float* noalias %source, float* noalias %dest) nounwind {
+define void @bitcast_mismatch_scalar_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_mismatch_scalar_size
-; CHECK-SAME: (float* noalias [[SOURCE:%.*]], float* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load float, float* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call float bitcast (i64 (i64)* @func_i64 to float (float)*)(float [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store float [[CALL]], float* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load float, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call float @func_i64(float [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store float [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load float, float* %source, align 8
- %call = call float bitcast (i64 (i64)* @func_i64 to float (float)*)(float %tmp) nounwind
- store float %call, float* %dest, align 8
+ %tmp = load float, ptr %source, align 8
+ %call = call float @func_i64(float %tmp) nounwind
+ store float %call, ptr %dest, align 8
ret void
}
; Test cast between vectors with different bit sizes but the
; same number of elements
-define void @bitcast_mismatch_vector_element_and_bit_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
+define void @bitcast_mismatch_vector_element_and_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_mismatch_vector_element_and_bit_size
-; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load <2 x float>, <2 x float>* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)(<2 x float> [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load <2 x float>, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @func_v2i64(<2 x float> [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store <2 x float> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <2 x float>, <2 x float>* %source, align 8
- %call = call <2 x float> bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind
- store <2 x float> %call, <2 x float>* %dest, align 8
+ %tmp = load <2 x float>, ptr %source, align 8
+ %call = call <2 x float> @func_v2i64(<2 x float> %tmp) nounwind
+ store <2 x float> %call, ptr %dest, align 8
ret void
}
; Test cast between vectors with same number of bits and different
; numbers of elements
-define void @bitcast_vector_mismatched_number_elements(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind {
+define void @bitcast_vector_mismatched_number_elements(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector_mismatched_number_elements
-; CHECK-SAME: (<4 x float>* noalias [[SOURCE:%.*]], <4 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, <4 x float>* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)(<4 x float> [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store <4 x float> [[CALL]], <4 x float>* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> @func_v2i32(<4 x float> [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store <4 x float> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <4 x float>, <4 x float>* %source, align 8
- %call = call <4 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)(<4 x float> %tmp) nounwind
- store <4 x float> %call, <4 x float>* %dest, align 8
+ %tmp = load <4 x float>, ptr %source, align 8
+ %call = call <4 x float> @func_v2i32(<4 x float> %tmp) nounwind
+ store <4 x float> %call, ptr %dest, align 8
ret void
}
; Test cast between vector and scalar with different number of bits
-define void @bitcast_vector_scalar_mismatched_bit_size(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind {
+define void @bitcast_vector_scalar_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector_scalar_mismatched_bit_size
-; CHECK-SAME: (<4 x float>* noalias [[SOURCE:%.*]], <4 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, <4 x float>* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)(<4 x float> [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store <4 x float> [[CALL]], <4 x float>* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> @func_i64(<4 x float> [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store <4 x float> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <4 x float>, <4 x float>* %source, align 8
- %call = call <4 x float> bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)(<4 x float> %tmp) nounwind
- store <4 x float> %call, <4 x float>* %dest, align 8
+ %tmp = load <4 x float>, ptr %source, align 8
+ %call = call <4 x float> @func_i64(<4 x float> %tmp) nounwind
+ store <4 x float> %call, ptr %dest, align 8
ret void
}
; Test cast between vector of pointers and scalar with different number of bits
-define void @bitcast_vector_ptrs_scalar_mismatched_bit_size(<4 x i32*>* noalias %source, <4 x i32*>* noalias %dest) nounwind {
+define void @bitcast_vector_ptrs_scalar_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_vector_ptrs_scalar_mismatched_bit_size
-; CHECK-SAME: (<4 x i32*>* noalias [[SOURCE:%.*]], <4 x i32*>* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load <4 x i32*>, <4 x i32*>* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call <4 x i32*> bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)(<4 x i32*> [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store <4 x i32*> [[CALL]], <4 x i32*>* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load <4 x ptr>, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call <4 x ptr> @func_i64(<4 x ptr> [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store <4 x ptr> [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load <4 x i32*>, <4 x i32*>* %source, align 8
- %call = call <4 x i32*> bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)(<4 x i32*> %tmp) nounwind
- store <4 x i32*> %call, <4 x i32*>* %dest, align 8
+ %tmp = load <4 x ptr>, ptr %source, align 8
+ %call = call <4 x ptr> @func_i64(<4 x ptr> %tmp) nounwind
+ store <4 x ptr> %call, ptr %dest, align 8
ret void
}
; Test cast from scalar to vector of pointers with same number of bits
; We don't know the pointer size at this point, so this can't be done
-define void @bitcast_scalar_vector_ptrs_same_size(i64* noalias %source, i64* noalias %dest) nounwind {
+define void @bitcast_scalar_vector_ptrs_same_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_scalar_vector_ptrs_same_size
-; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call i64 bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)(i64 [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store i64 [[CALL]], i64* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load i64, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call i64 @func_v2i32p(i64 [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store i64 [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load i64, i64* %source, align 8
- %call = call i64 bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)(i64 %tmp) nounwind
- store i64 %call, i64* %dest, align 8
+ %tmp = load i64, ptr %source, align 8
+ %call = call i64 @func_v2i32p(i64 %tmp) nounwind
+ store i64 %call, ptr %dest, align 8
ret void
}
; Test cast between scalar and vector with different number of bits
-define void @bitcast_scalar_vector_mismatched_bit_size(i64* noalias %source, i64* noalias %dest) nounwind {
+define void @bitcast_scalar_vector_mismatched_bit_size(ptr noalias %source, ptr noalias %dest) nounwind {
; CHECK-LABEL: define void @bitcast_scalar_vector_mismatched_bit_size
-; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] {
+; CHECK-SAME: (ptr noalias [[SOURCE:%.*]], ptr noalias [[DEST:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[SOURCE]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call i64 bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)(i64 [[TMP]]) #[[ATTR1]]
-; CHECK-NEXT: store i64 [[CALL]], i64* [[DEST]], align 8
+; CHECK-NEXT: [[TMP:%.*]] = load i64, ptr [[SOURCE]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call i64 @func_v4f32(i64 [[TMP]]) #[[ATTR1]]
+; CHECK-NEXT: store i64 [[CALL]], ptr [[DEST]], align 8
; CHECK-NEXT: ret void
;
entry:
- %tmp = load i64, i64* %source, align 8
- %call = call i64 bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)(i64 %tmp) nounwind
- store i64 %call, i64* %dest, align 8
+ %tmp = load i64, ptr %source, align 8
+ %call = call i64 @func_v4f32(i64 %tmp) nounwind
+ store i64 %call, ptr %dest, align 8
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -S -passes=instcombine < %s | FileCheck %s
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
; Instcombine should preserve metadata and alignment while
; folding a bitcast into a store.
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"
-%struct.A = type { i32 (...)** }
+%struct.A = type { ptr }
-@G = external constant [5 x i8*]
+@G = external constant [5 x ptr]
-define void @foo(i32 %x, float* %p) nounwind {
+define void @foo(i32 %x, ptr %p) nounwind {
; CHECK-LABEL: define void @foo
-; CHECK-SAME: (i32 [[X:%.*]], float* [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[P]] to i32*
-; CHECK-NEXT: store i32 [[X]], i32* [[TMP0]], align 16, !noalias !0, !llvm.access.group [[ACC_GRP3:![0-9]+]]
+; CHECK-NEXT: store i32 [[X]], ptr [[P]], align 16, !noalias !0, !llvm.access.group [[ACC_GRP3:![0-9]+]]
; CHECK-NEXT: ret void
;
entry:
%x.cast = bitcast i32 %x to float
- store float %x.cast, float* %p, align 16, !noalias !0, !llvm.access.group !3
+ store float %x.cast, ptr %p, align 16, !noalias !0, !llvm.access.group !3
ret void
}
; This transformation would not be safe since we would need to use addrspacecast
; and addrspacecast is not guaranteed to be a no-op cast.
-define void @bar(i8 addrspace(1)* %a, i8** %b) nounwind {
+define void @bar(ptr addrspace(1) %a, ptr %b) nounwind {
; CHECK-LABEL: define void @bar
-; CHECK-SAME: (i8 addrspace(1)* [[A:%.*]], i8** [[B:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (ptr addrspace(1) [[A:%.*]], ptr [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CAST:%.*]] = bitcast i8** [[B]] to i8 addrspace(1)**
-; CHECK-NEXT: store i8 addrspace(1)* [[A]], i8 addrspace(1)** [[CAST]], align 8
+; CHECK-NEXT: store ptr addrspace(1) [[A]], ptr [[B]], align 8
; CHECK-NEXT: ret void
;
entry:
- %cast = bitcast i8** %b to i8 addrspace(1)**
- store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
+ store ptr addrspace(1) %a, ptr %b
ret void
}
; bitcast of the swifterror which is invalid.
%swift.error = type opaque
-define void @swifterror_store(i64* %x, %swift.error** swifterror %err) {
+define void @swifterror_store(ptr %x, ptr swifterror %err) {
; CHECK-LABEL: define void @swifterror_store
-; CHECK-SAME: (i64* [[X:%.*]], %swift.error** swifterror [[ERR:%.*]]) {
+; CHECK-SAME: (ptr [[X:%.*]], ptr swifterror [[ERR:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CASTED:%.*]] = bitcast i64* [[X]] to %swift.error*
-; CHECK-NEXT: store %swift.error* [[CASTED]], %swift.error** [[ERR]], align 8
+; CHECK-NEXT: store ptr [[X]], ptr [[ERR]], align 8
; CHECK-NEXT: ret void
;
entry:
- %casted = bitcast i64* %x to %swift.error*
- store %swift.error* %casted, %swift.error** %err
+ store ptr %x, ptr %err
ret void
}
-define void @ppcf128_ones_store(ppc_fp128* %dest) {
+define void @ppcf128_ones_store(ptr %dest) {
; CHECK-LABEL: define void @ppcf128_ones_store
-; CHECK-SAME: (ppc_fp128* [[DEST:%.*]]) {
+; CHECK-SAME: (ptr [[DEST:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: store ppc_fp128 0xMFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ppc_fp128* [[DEST]], align 16
+; CHECK-NEXT: store ppc_fp128 0xMFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ptr [[DEST]], align 16
; CHECK-NEXT: ret void
;
entry:
%int = or i128 0, 340282366920938463463374607431768211455 ; 128 ones
%val = bitcast i128 %int to ppc_fp128
- store ppc_fp128 %val, ppc_fp128* %dest, align 16
+ store ppc_fp128 %val, ptr %dest, align 16
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
target datalayout = "e-p:32:32"
target triple = "i686-pc-linux-gnu"
declare void @takes_i32(i32)
-declare void @takes_i32_inalloca(i32* inalloca(i32))
+declare void @takes_i32_inalloca(ptr inalloca(i32))
define void @f() {
; CHECK-LABEL: define void @f() {
; CHECK-NEXT: [[ARGS:%.*]] = alloca inalloca i32, align 4
-; CHECK-NEXT: call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* nonnull inalloca(i32) [[ARGS]])
+; CHECK-NEXT: call void @takes_i32(ptr nonnull inalloca(i32) [[ARGS]])
; CHECK-NEXT: ret void
;
%args = alloca inalloca i32
- call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca(i32) %args)
+ call void @takes_i32(ptr inalloca(i32) %args)
ret void
}
define void @g() {
; CHECK-LABEL: define void @g() {
-; CHECK-NEXT: call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0)
+; CHECK-NEXT: call void @takes_i32_inalloca(i32 0)
; CHECK-NEXT: ret void
;
- call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0)
+ call void @takes_i32_inalloca(i32 0)
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
target datalayout = "e-p:32:32"
target triple = "i686-pc-win32"
declare token @llvm.call.preallocated.setup(i32)
-declare i8* @llvm.call.preallocated.arg(token, i32)
+declare ptr @llvm.call.preallocated.arg(token, i32)
declare void @takes_i32(i32)
-declare void @takes_i32_preallocated(i32* preallocated(i32))
+declare void @takes_i32_preallocated(ptr preallocated(i32))
define void @f() {
; CHECK-LABEL: define void @f() {
; CHECK-NEXT: [[T:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
-; CHECK-NEXT: [[A:%.*]] = call i8* @llvm.call.preallocated.arg(token [[T]], i32 0) #[[ATTR1:[0-9]+]]
-; CHECK-NEXT: [[ARG:%.*]] = bitcast i8* [[A]] to i32*
-; CHECK-NEXT: call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* preallocated(i32) [[ARG]]) [ "preallocated"(token [[T]]) ]
+; CHECK-NEXT: [[A:%.*]] = call ptr @llvm.call.preallocated.arg(token [[T]], i32 0) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: call void @takes_i32(ptr preallocated(i32) [[A]]) [ "preallocated"(token [[T]]) ]
; CHECK-NEXT: ret void
;
%t = call token @llvm.call.preallocated.setup(i32 1)
- %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(i32)
- %arg = bitcast i8* %a to i32*
- call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* preallocated(i32) %arg) ["preallocated"(token %t)]
+ %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(i32)
+ call void @takes_i32(ptr preallocated(i32) %a) ["preallocated"(token %t)]
ret void
}
define void @g() {
; CHECK-LABEL: define void @g() {
-; CHECK-NEXT: call void bitcast (void (i32*)* @takes_i32_preallocated to void (i32)*)(i32 0)
+; CHECK-NEXT: call void @takes_i32_preallocated(i32 0)
; CHECK-NEXT: ret void
;
- call void bitcast (void (i32*)* @takes_i32_preallocated to void (i32)*)(i32 0)
+ call void @takes_i32_preallocated(i32 0)
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
target datalayout = "E-p:64:64:64-p1:16:16:16-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
; Simple case, argument translatable without changing the value
-declare void @test1a(i8*)
+declare void @test1a(ptr)
-define void @test1(i32* %A) {
+define void @test1(ptr %A) {
; CHECK-LABEL: define void @test1
-; CHECK-SAME: (i32* [[A:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @test1a(i8* [[TMP1]])
+; CHECK-SAME: (ptr [[A:%.*]]) {
+; CHECK-NEXT: call void @test1a(ptr [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (i8*)* @test1a to void (i32*)*)( i32* %A )
+ call void @test1a( ptr %A )
ret void
}
; Should not do because of change in address space of the parameter
-define void @test1_as1_illegal(i32 addrspace(1)* %A) {
+define void @test1_as1_illegal(ptr addrspace(1) %A) {
; CHECK-LABEL: define void @test1_as1_illegal
-; CHECK-SAME: (i32 addrspace(1)* [[A:%.*]]) {
-; CHECK-NEXT: call void bitcast (void (i8*)* @test1a to void (i32 addrspace(1)*)*)(i32 addrspace(1)* [[A]])
+; CHECK-SAME: (ptr addrspace(1) [[A:%.*]]) {
+; CHECK-NEXT: call void @test1a(ptr addrspace(1) [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (i8*)* @test1a to void (i32 addrspace(1)*)*)(i32 addrspace(1)* %A)
+ call void @test1a(ptr addrspace(1) %A)
ret void
}
; Test1, but the argument has a different sized address-space
-declare void @test1a_as1(i8 addrspace(1)*)
+declare void @test1a_as1(ptr addrspace(1))
; This one is OK to perform
-define void @test1_as1(i32 addrspace(1)* %A) {
+define void @test1_as1(ptr addrspace(1) %A) {
; CHECK-LABEL: define void @test1_as1
-; CHECK-SAME: (i32 addrspace(1)* [[A:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[A]] to i8 addrspace(1)*
-; CHECK-NEXT: call void @test1a_as1(i8 addrspace(1)* [[TMP1]])
+; CHECK-SAME: (ptr addrspace(1) [[A:%.*]]) {
+; CHECK-NEXT: call void @test1a_as1(ptr addrspace(1) [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (i8 addrspace(1)*)* @test1a_as1 to void (i32 addrspace(1)*)*)(i32 addrspace(1)* %A )
+ call void @test1a_as1(ptr addrspace(1) %A )
ret void
}
define i32 @test2(i32 %A) {
; CHECK-LABEL: define i32 @test2
; CHECK-SAME: (i32 [[A:%.*]]) {
-; CHECK-NEXT: call void bitcast (void (i8)* @test2a to void (i32)*)(i32 [[A]])
+; CHECK-NEXT: call void @test2a(i32 [[A]])
; CHECK-NEXT: ret i32 [[A]]
;
- call void bitcast (void (i8)* @test2a to void (i32)*)( i32 %A )
+ call void @test2a( i32 %A )
ret i32 %A
}
; CHECK-NEXT: unreachable
;
define void @test3(i8 %A, i8 %B) {
- call void bitcast (void (i8, ...)* @test3a to void (i8, i8)*)( i8 %A, i8 %B)
+ call void @test3a( i8 %A, i8 %B)
ret void
}
define i32 @test4() {
; CHECK-LABEL: define i32 @test4() {
-; CHECK-NEXT: [[X:%.*]] = call i32 bitcast (i8 ()* @test4a to i32 ()*)()
+; CHECK-NEXT: [[X:%.*]] = call i32 @test4a()
; CHECK-NEXT: ret i32 [[X]]
;
- %X = call i32 bitcast (i8 ()* @test4a to i32 ()*)( ) ; <i32> [#uses=1]
+ %X = call i32 @test4a( ) ; <i32> [#uses=1]
ret i32 %X
}
; CHECK-NEXT: [[X:%.*]] = call i32 @test6a(i32 0)
; CHECK-NEXT: ret i32 [[X]]
;
- %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( )
+ %X = call i32 @test6a( )
ret i32 %X
}
; CHECK-NEXT: call void @test7a()
; CHECK-NEXT: ret void
;
- call void bitcast (void ()* @test7a to void (i32)*)( i32 5 )
+ call void @test7a( i32 5 )
ret void
}
; rdar://7590304
declare void @test8a()
-define i8* @test8() personality i32 (...)* @__gxx_personality_v0 {
-; CHECK-LABEL: define i8* @test8() personality i32 (...)* @__gxx_personality_v0 {
+define ptr @test8() personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define ptr @test8() personality ptr @__gxx_personality_v0 {
; CHECK-NEXT: invoke void @test8a()
; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TRY_HANDLER:%.*]]
; CHECK: invoke.cont:
; CHECK-NEXT: unreachable
; CHECK: try.handler:
-; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
-; CHECK-NEXT: ret i8* null
+; CHECK-NEXT: ret ptr null
;
; Don't turn this into "unreachable": the callee and caller don't agree in
; calling conv, but the implementation of test8a may actually end up using the
unreachable
try.handler: ; preds = %entry
- %exn = landingpad {i8*, i32}
+ %exn = landingpad {ptr, i32}
cleanup
- ret i8* null
+ ret ptr null
}
declare i32 @__gxx_personality_v0(...)
; Don't turn this into a direct call, because test9x is just a prototype and
; doing so will make it varargs.
; rdar://9038601
-declare i8* @test9x(i8*, i8*, ...) noredzone
-define i8* @test9(i8* %arg, i8* %tmp3) nounwind ssp noredzone {
-; CHECK-LABEL: define i8* @test9
-; CHECK-SAME: (i8* [[ARG:%.*]], i8* [[TMP3:%.*]]) #[[ATTR1:[0-9]+]] {
+declare ptr @test9x(ptr, ptr, ...) noredzone
+define ptr @test9(ptr %arg, ptr %tmp3) nounwind ssp noredzone {
+; CHECK-LABEL: define ptr @test9
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr [[TMP3:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @test9x to i8* (i8*, i8*)*)(i8* [[ARG]], i8* [[TMP3]]) #[[ATTR2:[0-9]+]]
-; CHECK-NEXT: ret i8* [[CALL]]
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @test9x(ptr [[ARG]], ptr [[TMP3]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: ret ptr [[CALL]]
;
entry:
- %call = call i8* bitcast (i8* (i8*, i8*, ...)* @test9x to i8* (i8*, i8*)*)(i8* %arg, i8* %tmp3) noredzone
- ret i8* %call
+ %call = call ptr @test9x(ptr %arg, ptr %tmp3) noredzone
+ ret ptr %call
}
; Parameter that's a vector of pointers
-declare void @test10a(<2 x i8*>)
+declare void @test10a(<2 x ptr>)
-define void @test10(<2 x i32*> %A) {
+define void @test10(<2 x ptr> %A) {
; CHECK-LABEL: define void @test10
-; CHECK-SAME: (<2 x i32*> [[A:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32*> [[A]] to <2 x i8*>
-; CHECK-NEXT: call void @test10a(<2 x i8*> [[TMP1]])
+; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {
+; CHECK-NEXT: call void @test10a(<2 x ptr> [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (<2 x i8*>)* @test10a to void (<2 x i32*>)*)(<2 x i32*> %A)
+ call void @test10a(<2 x ptr> %A)
ret void
}
; Don't transform because different address spaces
-declare void @test10a_mixed_as(<2 x i8 addrspace(1)*>)
+declare void @test10a_mixed_as(<2 x ptr addrspace(1)>)
-define void @test10_mixed_as(<2 x i8*> %A) {
+define void @test10_mixed_as(<2 x ptr> %A) {
; CHECK-LABEL: define void @test10_mixed_as
-; CHECK-SAME: (<2 x i8*> [[A:%.*]]) {
-; CHECK-NEXT: call void bitcast (void (<2 x i8 addrspace(1)*>)* @test10a_mixed_as to void (<2 x i8*>)*)(<2 x i8*> [[A]])
+; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {
+; CHECK-NEXT: call void @test10a_mixed_as(<2 x ptr> [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (<2 x i8 addrspace(1)*>)* @test10a_mixed_as to void (<2 x i8*>)*)(<2 x i8*> %A)
+ call void @test10a_mixed_as(<2 x ptr> %A)
ret void
}
; Return type that's a pointer
-define i8* @test11a() {
-; CHECK-LABEL: define i8* @test11a() {
-; CHECK-NEXT: ret i8* null
+define ptr @test11a() {
+; CHECK-LABEL: define ptr @test11a() {
+; CHECK-NEXT: ret ptr null
;
- ret i8* zeroinitializer
+ ret ptr zeroinitializer
}
-define i32* @test11() {
-; CHECK-LABEL: define i32* @test11() {
-; CHECK-NEXT: [[X:%.*]] = call i8* @test11a()
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[X]] to i32*
-; CHECK-NEXT: ret i32* [[TMP1]]
+define ptr @test11() {
+; CHECK-LABEL: define ptr @test11() {
+; CHECK-NEXT: [[X:%.*]] = call ptr @test11a()
+; CHECK-NEXT: ret ptr [[X]]
;
- %X = call i32* bitcast (i8* ()* @test11a to i32* ()*)()
- ret i32* %X
+ %X = call ptr @test11a()
+ ret ptr %X
}
; Return type that's a pointer with a different address space
-define i8 addrspace(1)* @test11a_mixed_as() {
-; CHECK-LABEL: define i8 addrspace(1)* @test11a_mixed_as() {
-; CHECK-NEXT: ret i8 addrspace(1)* null
+define ptr addrspace(1) @test11a_mixed_as() {
+; CHECK-LABEL: define ptr addrspace(1) @test11a_mixed_as() {
+; CHECK-NEXT: ret ptr addrspace(1) null
;
- ret i8 addrspace(1)* zeroinitializer
+ ret ptr addrspace(1) zeroinitializer
}
-define i8* @test11_mixed_as() {
-; CHECK-LABEL: define i8* @test11_mixed_as() {
-; CHECK-NEXT: [[X:%.*]] = call i8* bitcast (i8 addrspace(1)* ()* @test11a_mixed_as to i8* ()*)()
-; CHECK-NEXT: ret i8* [[X]]
+define ptr @test11_mixed_as() {
+; CHECK-LABEL: define ptr @test11_mixed_as() {
+; CHECK-NEXT: [[X:%.*]] = call ptr @test11a_mixed_as()
+; CHECK-NEXT: ret ptr [[X]]
;
- %X = call i8* bitcast (i8 addrspace(1)* ()* @test11a_mixed_as to i8* ()*)()
- ret i8* %X
+ %X = call ptr ()* @test11a_mixed_as()
+ ret ptr %X
}
; Return type that's a vector of pointers
-define <2 x i8*> @test12a() {
-; CHECK-LABEL: define <2 x i8*> @test12a() {
-; CHECK-NEXT: ret <2 x i8*> zeroinitializer
+define <2 x ptr> @test12a() {
+; CHECK-LABEL: define <2 x ptr> @test12a() {
+; CHECK-NEXT: ret <2 x ptr> zeroinitializer
;
- ret <2 x i8*> zeroinitializer
+ ret <2 x ptr> zeroinitializer
}
-define <2 x i32*> @test12() {
-; CHECK-LABEL: define <2 x i32*> @test12() {
-; CHECK-NEXT: [[X:%.*]] = call <2 x i8*> @test12a()
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i8*> [[X]] to <2 x i32*>
-; CHECK-NEXT: ret <2 x i32*> [[TMP1]]
+define <2 x ptr> @test12() {
+; CHECK-LABEL: define <2 x ptr> @test12() {
+; CHECK-NEXT: [[X:%.*]] = call <2 x ptr> @test12a()
+; CHECK-NEXT: ret <2 x ptr> [[X]]
;
- %X = call <2 x i32*> bitcast (<2 x i8*> ()* @test12a to <2 x i32*> ()*)()
- ret <2 x i32*> %X
+ %X = call <2 x ptr> @test12a()
+ ret <2 x ptr> %X
}
-define <2 x i8 addrspace(1)*> @test12a_mixed_as() {
-; CHECK-LABEL: define <2 x i8 addrspace(1)*> @test12a_mixed_as() {
-; CHECK-NEXT: ret <2 x i8 addrspace(1)*> zeroinitializer
+define <2 x ptr addrspace(1)> @test12a_mixed_as() {
+; CHECK-LABEL: define <2 x ptr addrspace(1)> @test12a_mixed_as() {
+; CHECK-NEXT: ret <2 x ptr addrspace(1)> zeroinitializer
;
- ret <2 x i8 addrspace(1)*> zeroinitializer
+ ret <2 x ptr addrspace(1)> zeroinitializer
}
-define <2 x i8*> @test12_mixed_as() {
-; CHECK-LABEL: define <2 x i8*> @test12_mixed_as() {
-; CHECK-NEXT: [[X:%.*]] = call <2 x i8*> bitcast (<2 x i8 addrspace(1)*> ()* @test12a_mixed_as to <2 x i8*> ()*)()
-; CHECK-NEXT: ret <2 x i8*> [[X]]
+define <2 x ptr> @test12_mixed_as() {
+; CHECK-LABEL: define <2 x ptr> @test12_mixed_as() {
+; CHECK-NEXT: [[X:%.*]] = call <2 x ptr> @test12a_mixed_as()
+; CHECK-NEXT: ret <2 x ptr> [[X]]
;
- %X = call <2 x i8*> bitcast (<2 x i8 addrspace(1)*> ()* @test12a_mixed_as to <2 x i8*> ()*)()
- ret <2 x i8*> %X
+ %X = call <2 x ptr> @test12a_mixed_as()
+ ret <2 x ptr> %X
}
; Mix parameter that's a vector of integers and pointers of the same size
declare void @test13a(<2 x i64>)
-define void @test13(<2 x i32*> %A) {
+define void @test13(<2 x ptr> %A) {
; CHECK-LABEL: define void @test13
-; CHECK-SAME: (<2 x i32*> [[A:%.*]]) {
-; CHECK-NEXT: call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> [[A]])
+; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {
+; CHECK-NEXT: call void @test13a(<2 x ptr> [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> %A)
+ call void @test13a(<2 x ptr> %A)
ret void
}
; Mix parameter that's a vector of integers and pointers of the same
; size, but the other way around
-declare void @test14a(<2 x i8*>)
+declare void @test14a(<2 x ptr>)
define void @test14(<2 x i64> %A) {
; CHECK-LABEL: define void @test14
; CHECK-SAME: (<2 x i64> [[A:%.*]]) {
-; CHECK-NEXT: call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> [[A]])
+; CHECK-NEXT: call void @test14a(<2 x i64> [[A]])
; CHECK-NEXT: ret void
;
- call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> %A)
+ call void @test14a(<2 x i64> %A)
ret void
}
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[X]] to i32
; CHECK-NEXT: ret i32 [[TMP1]]
;
- %X = call i32 bitcast (<2 x i16> ()* @test15a to i32 ()*)( )
+ %X = call i32 @test15a( )
ret i32 %X
}
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[X]] to <2 x i16>
; CHECK-NEXT: ret <2 x i16> [[TMP1]]
;
- %X = call <2 x i16> bitcast (i32 ()* @test16a to <2 x i16> ()*)( )
+ %X = call <2 x i16> @test16a( )
ret <2 x i16> %X
}
ret i32 %C
}
-define void @non_vararg(i8*, i32) {
+define void @non_vararg(ptr, i32) {
; CHECK-LABEL: define void @non_vararg
-; CHECK-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
+; CHECK-SAME: (ptr [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
; CHECK-NEXT: ret void
;
ret void
}
-define void @test_cast_to_vararg(i8* %this) {
+define void @test_cast_to_vararg(ptr %this) {
; CHECK-LABEL: define void @test_cast_to_vararg
-; CHECK-SAME: (i8* [[THIS:%.*]]) {
-; CHECK-NEXT: call void @non_vararg(i8* [[THIS]], i32 42)
+; CHECK-SAME: (ptr [[THIS:%.*]]) {
+; CHECK-NEXT: call void @non_vararg(ptr [[THIS]], i32 42)
; CHECK-NEXT: ret void
;
- call void (i8*, ...) bitcast (void (i8*, i32)* @non_vararg to void (i8*, ...)*)(i8* %this, i32 42)
+ call void (ptr, ...) @non_vararg(ptr %this, i32 42)
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 -passes=instcombine -S < %s | FileCheck %s
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-declare void @foo(i8*)
-declare void @bar(i8 addrspace(1)*)
+declare void @foo(ptr)
+declare void @bar(ptr addrspace(1))
define void @nonnullAfterBitCast() {
; CHECK-LABEL: define void @nonnullAfterBitCast() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[I]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[TMP1]])
+; CHECK-NEXT: call void @foo(ptr nonnull [[I]])
; CHECK-NEXT: ret void
;
entry:
%i = alloca i32, align 4
- %tmp1 = bitcast i32* %i to i8*
- call void @foo(i8* %tmp1)
+ call void @foo(ptr %i)
ret void
}
; CHECK-NEXT: entry:
; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64
; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]])
+; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to ptr
+; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]])
; CHECK-NEXT: ret void
;
entry:
%b = zext i8 %a to i32 ; <- %b is >= 0
%c = add nsw nuw i32 %b, 2 ; <- %c is > 0
%sext = sext i32 %c to i64 ; <- %sext cannot be 0 because %c is not 0
- %i2p = inttoptr i64 %sext to i8* ; <- no-op int2ptr cast
- call void @foo(i8* %i2p)
+ %i2p = inttoptr i64 %sext to ptr ; <- no-op int2ptr cast
+ call void @foo(ptr %i2p)
ret void
}
; CHECK-NEXT: entry:
; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64
; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]])
+; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to ptr
+; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]])
; CHECK-NEXT: ret void
;
entry:
%b = zext i8 %a to i32 ; <- %b is >= 0
%c = add nsw nuw i32 %b, 2 ; <- %c is > 0
%zext = zext i32 %c to i64 ; <- %zext cannot be 0 because %c is not 0
- %i2p = inttoptr i64 %zext to i8* ; <- no-op int2ptr cast
- call void @foo(i8* %i2p)
+ %i2p = inttoptr i64 %zext to ptr ; <- no-op int2ptr cast
+ call void @foo(ptr %i2p)
ret void
}
; CHECK-NEXT: entry:
; CHECK-NEXT: [[NZ:%.*]] = sdiv exact i32 100, [[U]]
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[NZ]] to i64
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]])
+; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to ptr
+; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]])
; CHECK-NEXT: [[NZ_2:%.*]] = sdiv exact i64 100, [[LU]]
-; CHECK-NEXT: [[I2P_2:%.*]] = inttoptr i64 [[NZ_2]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[I2P_2]])
+; CHECK-NEXT: [[I2P_2:%.*]] = inttoptr i64 [[NZ_2]] to ptr
+; CHECK-NEXT: call void @foo(ptr nonnull [[I2P_2]])
; CHECK-NEXT: ret void
;
entry:
%nz = sdiv exact i32 100, %u ; %nz cannot be null
- %i2p = inttoptr i32 %nz to i8* ; extending int2ptr as sizeof(i32) < sizeof(i8*)
- call void @foo(i8* %i2p)
+ %i2p = inttoptr i32 %nz to ptr ; extending int2ptr as sizeof(i32) < sizeof(ptr)
+ call void @foo(ptr %i2p)
%nz.2 = sdiv exact i64 100, %lu ; %nz.2 cannot be null
- %i2p.2 = inttoptr i64 %nz.2 to i8* ; no-op int2ptr as sizeof(i64) == sizeof(i8*)
- call void @foo(i8* %i2p.2)
+ %i2p.2 = inttoptr i64 %nz.2 to ptr ; no-op int2ptr as sizeof(i64) == sizeof(ptr)
+ call void @foo(ptr %i2p.2)
ret void
}
; CHECK-LABEL: define void @nonnullAfterPtr2Int() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[I2P:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]])
+; CHECK-NEXT: call void @foo(ptr nonnull [[A]])
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32
- %p2i = ptrtoint i32* %a to i64 ; no-op ptr2int as sizeof(i32*) == sizeof(i64)
- %i2p = inttoptr i64 %p2i to i8*
- call void @foo(i8* %i2p)
+ %p2i = ptrtoint ptr %a to i64 ; no-op ptr2int as sizeof(ptr) == sizeof(i64)
+ %i2p = inttoptr i64 %p2i to ptr
+ call void @foo(ptr %i2p)
ret void
}
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i128 [[LLU]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[TMP0:%.*]] = trunc i128 [[LLU]] to i64
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to i8*
-; CHECK-NEXT: call void @foo(i8* [[I2P]])
+; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to ptr
+; CHECK-NEXT: call void @foo(ptr [[I2P]])
; CHECK-NEXT: ret void
;
entry:
%cmp = icmp ne i128 %llu, 0
call void @llvm.assume(i1 %cmp) ; %llu != 0
- %i2p = inttoptr i128 %llu to i8* ; truncating int2ptr as sizeof(i128) > sizeof(i8*)
- call void @foo(i8* %i2p)
+ %i2p = inttoptr i128 %llu to ptr ; truncating int2ptr as sizeof(i128) > sizeof(ptr)
+ call void @foo(ptr %i2p)
ret void
}
; CHECK-LABEL: define void @maybenullAfterPtr2Int() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint i32* [[A]] to i64
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4294967292
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP1]] to i8*
-; CHECK-NEXT: call void @foo(i8* [[I2P]])
+; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT: call void @foo(ptr [[I2P]])
; CHECK-NEXT: ret void
;
entry:
%a = alloca i32
- %p2i = ptrtoint i32* %a to i32 ; truncating ptr2int as sizeof(i32*) > sizeof(i32)
- %i2p = inttoptr i32 %p2i to i8*
- call void @foo(i8* %i2p)
+ %p2i = ptrtoint ptr %a to i32 ; truncating ptr2int as sizeof(ptr) > sizeof(i32)
+ %i2p = inttoptr i32 %p2i to ptr
+ call void @foo(ptr %i2p)
ret void
}
-define void @maybenullAfterAddrspacecast(i8* nonnull %p) {
+define void @maybenullAfterAddrspacecast(ptr nonnull %p) {
; CHECK-LABEL: define void @maybenullAfterAddrspacecast
-; CHECK-SAME: (i8* nonnull [[P:%.*]]) {
+; CHECK-SAME: (ptr nonnull [[P:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADDRSPCAST:%.*]] = addrspacecast i8* [[P]] to i8 addrspace(1)*
-; CHECK-NEXT: call void @bar(i8 addrspace(1)* [[ADDRSPCAST]])
-; CHECK-NEXT: call void @foo(i8* nonnull [[P]])
+; CHECK-NEXT: [[ADDRSPCAST:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1)
+; CHECK-NEXT: call void @bar(ptr addrspace(1) [[ADDRSPCAST]])
+; CHECK-NEXT: call void @foo(ptr nonnull [[P]])
; CHECK-NEXT: ret void
;
entry:
- %addrspcast = addrspacecast i8* %p to i8 addrspace(1)*
+ %addrspcast = addrspacecast ptr %p to ptr addrspace(1)
; An address space cast can be "a no-op cast or a complex value modification,
; depending on the target and the address space pair". As a consequence, we
; cannot simply assume non-nullness of %p is preserved by the cast.
- call void @bar(i8 addrspace(1)* %addrspcast)
+ call void @bar(ptr addrspace(1) %addrspcast)
- call void @foo(i8* %p)
+ call void @foo(ptr %p)
ret void
}
+++ /dev/null
-; RUN: opt -opaque-pointers=0 -S --passes=instcombine %s | FileCheck %s
-
-; https://github.com/llvm/llvm-project/issues/56807
-%si16 = type { i8, i8 }
-
-declare void @foo(i16* %pixels)
-
-declare void @llvm.dbg.declare(metadata, metadata, metadata)
-
-; CHECK-LABEL: @toplevel(
-; CHECK: entry:
-; CHECK-NEXT: %pixels = alloca i16
-; CHECK-NEXT: call void @llvm.dbg.declare(metadata i16* %pixels, metadata ![[MD:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG:[0-9]+]]
-; CHECK-NEXT: call void @foo(i16* nonnull %pixels)
-; CHECK-NEXT: ret void
-define dso_local void @toplevel() {
-entry:
- %pixels = alloca %si16
- call void @llvm.dbg.declare(metadata %si16* %pixels, metadata !11, metadata !DIExpression()), !dbg !12
- %arraydecay = bitcast %si16* %pixels to i16*
- call void @foo(i16* nonnull %arraydecay)
- ret void
-}
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5}
-
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.1.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "test.cpp", directory: "/path/to/test_cpp")
-!2 = !{}
-!3 = !{i32 7, !"Dwarf Version", i32 4}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 4}
-!7 = distinct !DISubprogram(name: "toplevel", linkageName: "_Z8toplevelv", scope: !1, file: !1, line: 9, type: !8, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
-!8 = !DISubroutineType(types: !9)
-!9 = !{!10, !10}
-!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-; CHECK: ![[MD]] = !DILocalVariable(name: "pixels"
-!11 = !DILocalVariable(name: "pixels", arg: 1, scope: !7, file: !1, line: 9, type: !10)
-; CHECK: ![[DBG]] = !DILocation(line: 9, column: 16,
-!12 = !DILocation(line: 9, column: 16, scope: !7)
-; RUN: opt -opaque-pointers=0 -passes=instcombine %s -S -o - | FileCheck %s
+; RUN: opt -passes=instcombine %s -S -o - | FileCheck %s
; Verify that the eliminated instructions (bitcast, gep, load) are salvaged into
; a DIExpression.
;
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"
-%struct.entry = type { %struct.entry* }
+%struct.entry = type { ptr }
; This salvage can't currently occur safely (PR40628), however if/when that's
; ever fixed, then this is definitely a piece of test coverage that should
; be maintained.
-define void @salvage_load(%struct.entry** %queue) local_unnamed_addr #0 !dbg !14 {
+define void @salvage_load(ptr %queue) local_unnamed_addr #0 !dbg !14 {
entry:
- %im_not_dead = alloca %struct.entry*
- %0 = load %struct.entry*, %struct.entry** %queue, align 8, !dbg !19
- %1 = load %struct.entry*, %struct.entry** %queue, align 8, !dbg !19
- call void @llvm.dbg.value(metadata %struct.entry* %1, metadata !18, metadata !20), !dbg !19
+ %im_not_dead = alloca ptr
+ %0 = load ptr, ptr %queue, align 8, !dbg !19
+ %1 = load ptr, ptr %queue, align 8, !dbg !19
+ call void @llvm.dbg.value(metadata ptr %1, metadata !18, metadata !20), !dbg !19
; CHECK: define void @salvage_load
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* poison
- store %struct.entry* %1, %struct.entry** %im_not_dead, align 8
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr poison
+ store ptr %1, ptr %im_not_dead, align 8
ret void, !dbg !21
}
-define void @salvage_bitcast(%struct.entry* %queue) local_unnamed_addr #0 !dbg !22 {
+define void @salvage_bitcast(ptr %queue) local_unnamed_addr #0 !dbg !22 {
entry:
- %im_not_dead = alloca i8*
- %0 = bitcast %struct.entry* %queue to i8*, !dbg !23
- %1 = bitcast %struct.entry* %queue to i8*, !dbg !23
- call void @llvm.dbg.value(metadata i8* %1, metadata !24, metadata !20), !dbg !23
+ %im_not_dead = alloca ptr
+ call void @llvm.dbg.value(metadata ptr %queue, metadata !24, metadata !20), !dbg !23
; CHECK: define void @salvage_bitcast
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue,
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr %queue,
; CHECK-SAME: metadata !DIExpression(DW_OP_plus_uconst, 0))
- store i8* %1, i8** %im_not_dead, align 8
+ store ptr %queue, ptr %im_not_dead, align 8
ret void, !dbg !23
}
-define void @salvage_gep0(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !25 {
+define void @salvage_gep0(ptr %queue, ptr %end) local_unnamed_addr #0 !dbg !25 {
entry:
- %im_not_dead = alloca %struct.entry**
- %0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !26
- %1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !26
- call void @llvm.dbg.value(metadata %struct.entry** %1, metadata !27, metadata !20), !dbg !26
+ %im_not_dead = alloca ptr
+ %0 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !26
+ %1 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !26
+ call void @llvm.dbg.value(metadata ptr %1, metadata !27, metadata !20), !dbg !26
; CHECK: define void @salvage_gep0
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue,
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr %queue,
; CHECK-SAME: metadata !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_plus_uconst, 0, DW_OP_stack_value))
- store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
+ store ptr %1, ptr %im_not_dead, align 8
ret void, !dbg !26
}
-define void @salvage_gep1(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !28 {
+define void @salvage_gep1(ptr %queue, ptr %end) local_unnamed_addr #0 !dbg !28 {
entry:
- %im_not_dead = alloca %struct.entry**
- %0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !29
- %1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !29
- call void @llvm.dbg.value(metadata %struct.entry** %1, metadata !30, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !29
+ %im_not_dead = alloca ptr
+ %0 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !29
+ %1 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !29
+ call void @llvm.dbg.value(metadata ptr %1, metadata !30, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !29
; CHECK: define void @salvage_gep1
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue,
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr %queue,
; CHECK-SAME: metadata !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32))
- store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
+ store ptr %1, ptr %im_not_dead, align 8
ret void, !dbg !29
}
-define void @salvage_gep2(%struct.entry* %queue, %struct.entry* %end) local_unnamed_addr #0 !dbg !31 {
+define void @salvage_gep2(ptr %queue, ptr %end) local_unnamed_addr #0 !dbg !31 {
entry:
- %im_not_dead = alloca %struct.entry**
- %0 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !32
- %1 = getelementptr inbounds %struct.entry, %struct.entry* %queue, i32 -1, i32 0, !dbg !32
- call void @llvm.dbg.value(metadata %struct.entry** %1, metadata !33, metadata !DIExpression(DW_OP_stack_value)), !dbg !32
+ %im_not_dead = alloca ptr
+ %0 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !32
+ %1 = getelementptr inbounds %struct.entry, ptr %queue, i32 -1, i32 0, !dbg !32
+ call void @llvm.dbg.value(metadata ptr %1, metadata !33, metadata !DIExpression(DW_OP_stack_value)), !dbg !32
; CHECK: define void @salvage_gep2
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @llvm.dbg.value(metadata %struct.entry* %queue,
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr %queue,
; CHECK-SAME: metadata !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_stack_value))
- store %struct.entry** %1, %struct.entry*** %im_not_dead, align 8
+ store ptr %1, ptr %im_not_dead, align 8
ret void, !dbg !32
}
+++ /dev/null
-
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine,verify -S -o - | FileCheck %s
-
-; Hand-reduced from this example.
-; -g -O -mllvm -disable-llvm-optzns -gno-column-info
-; plus opt -opaque-pointers=0 -sroa -passes=instcombine -inline
-
-; #include <stdio.h>
-;
-; struct S1 {
-; int p1;
-; int p2;
-;
-; bool IsNull ( ) {
-; return p1 == 0;
-; }
-; };
-;
-; S1 foo ( void );
-;
-; int bar ( ) {
-;
-; S1 result = foo();
-;
-; if ( result.IsNull() )
-; return 0;
-;
-; result.p1 = 2;
-; result.p2 = 3;
-;
-; int* ptr = &result.p1;
-;
-; printf("%d", *ptr);
-; printf("%d", *(ptr+1));
-;
-; return result.p1 + 1;
-; }
-
-; CHECK: _Z3barv
-; CHECK: llvm.dbg.declare(metadata i64* %{{.*}}, metadata [[METADATA_IDX1:![0-9]+]]
-; CHECK-NOT: llvm.dbg.declare(metadata %struct.S1* %{{.*}}, metadata [[METADATA_IDX1]]
-; CHECK: ret
-; CHECK: DICompileUnit
-; CHECK: [[METADATA_IDX1]] = !DILocalVariable(name: "result"
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-%struct.S1 = type { i32, i32 }
-
-@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
-
-define dso_local i32 @_Z3barv() !dbg !7 {
-entry:
- %result = alloca i64, align 8
- %tmpcast = bitcast i64* %result to %struct.S1*
- %0 = bitcast i64* %result to i8*, !dbg !24
- call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !24
- call void @llvm.dbg.declare(metadata %struct.S1* %tmpcast, metadata !12, metadata !DIExpression()), !dbg !24
- %call = call i64 @_Z3foov(), !dbg !24
- store i64 %call, i64* %result, align 8, !dbg !24
- call void @llvm.dbg.value(metadata %struct.S1* %tmpcast, metadata !25, metadata !DIExpression()), !dbg !29
- %p1.i = getelementptr inbounds %struct.S1, %struct.S1* %tmpcast, i64 0, i32 0, !dbg !32
- %1 = load i32, i32* %p1.i, align 4, !dbg !32
- %cmp.i = icmp eq i32 %1, 0, !dbg !32
- br i1 %cmp.i, label %if.then, label %if.end, !dbg !38
-
-if.then: ; preds = %entry
- br label %cleanup, !dbg !38
-
-if.end: ; preds = %entry
-
- %p1 = bitcast i64* %result to i32*, !dbg !38
- store i32 2, i32* %p1, align 8, !dbg !38
- %p2 = getelementptr inbounds %struct.S1, %struct.S1* %tmpcast, i64 0, i32 1, !dbg !38
- store i32 3, i32* %p2, align 4, !dbg !38
- %p12 = bitcast i64* %result to i32*, !dbg !38
- call void @llvm.dbg.value(metadata i32* %p12, metadata !22, metadata !DIExpression()), !dbg !38
- %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 2), !dbg !38
- %add.ptr = getelementptr inbounds i32, i32* %p12, i64 1, !dbg !38
- %2 = load i32, i32* %add.ptr, align 4, !dbg !38
- %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 %2), !dbg !38
- %p15 = bitcast i64* %result to i32*, !dbg !38
- %3 = load i32, i32* %p15, align 8, !dbg !38
- %add = add nsw i32 %3, 1, !dbg !38
- br label %cleanup
-
-cleanup: ; preds = %if.end, %if.then
- %retval.0 = phi i32 [ 0, %if.then ], [ %add, %if.end ], !dbg !38
- %4 = bitcast i64* %result to i8*, !dbg !38
- call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %4) #4, !dbg !38
- ret i32 %retval.0, !dbg !38
-}
-
-declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
-
-declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
-
-declare dso_local i64 @_Z3foov() #3
-
-declare dso_local i32 @printf(i8*, ...) #3
-
-declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
-
-declare void @llvm.dbg.value(metadata, metadata, metadata) #2
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5}
-!llvm.ident = !{!6}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "test.cpp", directory: "")
-!2 = !{}
-!3 = !{i32 2, !"Dwarf Version", i32 4}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 4}
-!6 = !{!"clang"}
-!7 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 15, type: !8, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
-!8 = !DISubroutineType(types: !9)
-!9 = !{!10}
-!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!11 = !{!12, !22}
-!12 = !DILocalVariable(name: "result", scope: !7, file: !1, line: 17, type: !13)
-!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S1", file: !1, line: 4, size: 64, flags: DIFlagTypePassByValue, elements: !14, identifier: "_ZTS2S1")
-!14 = !{!15, !16, !17}
-!15 = !DIDerivedType(tag: DW_TAG_member, name: "p1", scope: !13, file: !1, line: 5, baseType: !10, size: 32)
-!16 = !DIDerivedType(tag: DW_TAG_member, name: "p2", scope: !13, file: !1, line: 6, baseType: !10, size: 32, offset: 32)
-!17 = !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 8, type: !18, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
-!18 = !DISubroutineType(types: !19)
-!19 = !{!20, !21}
-!20 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)
-!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
-!22 = !DILocalVariable(name: "ptr", scope: !7, file: !1, line: 25, type: !23)
-!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
-!24 = !DILocation(line: 17, scope: !7)
-!25 = !DILocalVariable(name: "this", arg: 1, scope: !26, type: !28, flags: DIFlagArtificial | DIFlagObjectPointer)
-!26 = distinct !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 8, type: !18, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !17, retainedNodes: !27)
-!27 = !{!25}
-!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
-!29 = !DILocation(line: 0, scope: !26, inlinedAt: !30)
-!30 = distinct !DILocation(line: 19, scope: !31)
-!31 = distinct !DILexicalBlock(scope: !7, file: !1, line: 19)
-!32 = !DILocation(line: 9, scope: !26, inlinedAt: !30)
-!38 = !DILocation(line: 0, scope: !7)
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -opaque-pointers=0 < %s -passes='instcombine<use-loop-info>' -S | FileCheck %s
+; RUN: opt < %s -passes='instcombine<use-loop-info>' -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
-define i32 @foo(i8* nocapture readnone %match, i32 %cur_match, i32 %best_len, i32 %scan_end, i32* nocapture readonly %prev, i32 %limit, i32 %chain_length, i8* nocapture readonly %win, i32 %wmask) {
+define i32 @foo(ptr nocapture readnone %match, i32 %cur_match, i32 %best_len, i32 %scan_end, ptr nocapture readonly %prev, i32 %limit, i32 %chain_length, ptr nocapture readonly %win, i32 %wmask) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT2:%.*]] = zext i32 [[CUR_MATCH:%.*]] to i64
-; CHECK-NEXT: [[ADD_PTR4:%.*]] = getelementptr inbounds i8, i8* [[WIN:%.*]], i64 [[IDX_EXT2]]
+; CHECK-NEXT: [[ADD_PTR4:%.*]] = getelementptr inbounds i8, ptr [[WIN:%.*]], i64 [[IDX_EXT2]]
; CHECK-NEXT: [[IDX_EXT1:%.*]] = zext i32 [[BEST_LEN:%.*]] to i64
-; CHECK-NEXT: [[ADD_PTR25:%.*]] = getelementptr inbounds i8, i8* [[ADD_PTR4]], i64 [[IDX_EXT1]]
-; CHECK-NEXT: [[ADD_PTR36:%.*]] = getelementptr inbounds i8, i8* [[ADD_PTR25]], i64 -1
-; CHECK-NEXT: [[I:%.*]] = bitcast i8* [[ADD_PTR36]] to i32*
-; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[I]], align 4
+; CHECK-NEXT: [[ADD_PTR25:%.*]] = getelementptr inbounds i8, ptr [[ADD_PTR4]], i64 [[IDX_EXT1]]
+; CHECK-NEXT: [[ADD_PTR36:%.*]] = getelementptr inbounds i8, ptr [[ADD_PTR25]], i64 -1
+; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ADD_PTR36]], align 4
; CHECK-NEXT: [[CMP7:%.*]] = icmp eq i32 [[I1]], [[SCAN_END:%.*]]
; CHECK-NEXT: br i1 [[CMP7]], label [[DO_END:%.*]], label [[IF_THEN_LR_PH:%.*]]
; CHECK: if.then.lr.ph:
; CHECK-NEXT: br label [[IF_THEN:%.*]]
; CHECK: do.body:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[I4:%.*]] to i64
-; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds i8, i8* [[WIN]], i64 [[IDX_EXT1]]
-; CHECK-NEXT: [[ADD_PTR22:%.*]] = getelementptr i8, i8* [[ADD_PTR1]], i64 -1
-; CHECK-NEXT: [[ADD_PTR3:%.*]] = getelementptr i8, i8* [[ADD_PTR22]], i64 [[IDX_EXT]]
-; CHECK-NEXT: [[I2:%.*]] = bitcast i8* [[ADD_PTR3]] to i32*
-; CHECK-NEXT: [[I3:%.*]] = load i32, i32* [[I2]], align 4
+; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds i8, ptr [[WIN]], i64 [[IDX_EXT1]]
+; CHECK-NEXT: [[ADD_PTR22:%.*]] = getelementptr i8, ptr [[ADD_PTR1]], i64 -1
+; CHECK-NEXT: [[ADD_PTR3:%.*]] = getelementptr i8, ptr [[ADD_PTR22]], i64 [[IDX_EXT]]
+; CHECK-NEXT: [[I3:%.*]] = load i32, ptr [[ADD_PTR3]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I3]], [[SCAN_END]]
; CHECK-NEXT: br i1 [[CMP]], label [[DO_END]], label [[IF_THEN]]
; CHECK: if.then:
; CHECK-NEXT: [[CHAIN_LENGTH_ADDR_08:%.*]] = phi i32 [ [[CHAIN_LENGTH:%.*]], [[IF_THEN_LR_PH]] ], [ [[DEC:%.*]], [[DO_BODY]] ]
; CHECK-NEXT: [[AND:%.*]] = and i32 [[CUR_MATCH_ADDR_09]], [[WMASK:%.*]]
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[AND]] to i64
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[PREV:%.*]], i64 [[IDXPROM]]
-; CHECK-NEXT: [[I4]] = load i32, i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PREV:%.*]], i64 [[IDXPROM]]
+; CHECK-NEXT: [[I4]] = load i32, ptr [[ARRAYIDX]], align 4
; CHECK-NEXT: [[CMP4:%.*]] = icmp ugt i32 [[I4]], [[LIMIT:%.*]]
; CHECK-NEXT: br i1 [[CMP4]], label [[LAND_LHS_TRUE:%.*]], label [[DO_END]]
; CHECK: land.lhs.true:
;
entry:
%idx.ext2 = zext i32 %cur_match to i64
- %add.ptr4 = getelementptr inbounds i8, i8* %win, i64 %idx.ext2
+ %add.ptr4 = getelementptr inbounds i8, ptr %win, i64 %idx.ext2
%idx.ext1 = zext i32 %best_len to i64
- %add.ptr25 = getelementptr inbounds i8, i8* %add.ptr4, i64 %idx.ext1
- %add.ptr36 = getelementptr inbounds i8, i8* %add.ptr25, i64 -1
- %i = bitcast i8* %add.ptr36 to i32*
- %i1 = load i32, i32* %i, align 4
+ %add.ptr25 = getelementptr inbounds i8, ptr %add.ptr4, i64 %idx.ext1
+ %add.ptr36 = getelementptr inbounds i8, ptr %add.ptr25, i64 -1
+ %i1 = load i32, ptr %add.ptr36, align 4
%cmp7 = icmp eq i32 %i1, %scan_end
br i1 %cmp7, label %do.end, label %if.then.lr.ph
%chain_length.addr.0 = phi i32 [ %dec, %land.lhs.true ]
%cur_match.addr.0 = phi i32 [ %i4, %land.lhs.true ]
%idx.ext = zext i32 %cur_match.addr.0 to i64
- %add.ptr = getelementptr inbounds i8, i8* %win, i64 %idx.ext
- %add.ptr2 = getelementptr inbounds i8, i8* %add.ptr, i64 %idx.ext1
- %add.ptr3 = getelementptr inbounds i8, i8* %add.ptr2, i64 -1
- %i2 = bitcast i8* %add.ptr3 to i32*
- %i3 = load i32, i32* %i2, align 4
+ %add.ptr = getelementptr inbounds i8, ptr %win, i64 %idx.ext
+ %add.ptr2 = getelementptr inbounds i8, ptr %add.ptr, i64 %idx.ext1
+ %add.ptr3 = getelementptr inbounds i8, ptr %add.ptr2, i64 -1
+ %i3 = load i32, ptr %add.ptr3, align 4
%cmp = icmp eq i32 %i3, %scan_end
br i1 %cmp, label %do.end, label %if.then
%chain_length.addr.08 = phi i32 [ %chain_length, %if.then.lr.ph ], [ %chain_length.addr.0, %do.body ]
%and = and i32 %cur_match.addr.09, %wmask
%idxprom = zext i32 %and to i64
- %arrayidx = getelementptr inbounds i32, i32* %prev, i64 %idxprom
- %i4 = load i32, i32* %arrayidx, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %prev, i64 %idxprom
+ %i4 = load i32, ptr %arrayidx, align 4
%cmp4 = icmp ugt i32 %i4, %limit
br i1 %cmp4, label %land.lhs.true, label %do.end
ret i32 %cont.0
}
-declare void @blackhole(<2 x i8*>)
+declare void @blackhole(<2 x ptr>)
-define void @PR37005(i8* %base, i8** %in) {
+define void @PR37005(ptr %base, ptr %in) {
; CHECK-LABEL: @PR37005(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds i8*, i8** [[IN:%.*]], i64 undef
-; CHECK-NEXT: [[E4:%.*]] = getelementptr inbounds i8*, i8** [[E2]], <2 x i64> <i64 0, i64 1>
-; CHECK-NEXT: [[PI1:%.*]] = ptrtoint <2 x i8**> [[E4]] to <2 x i64>
+; CHECK-NEXT: [[E1:%.*]] = getelementptr inbounds ptr, ptr [[IN:%.*]], i64 undef
+; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds ptr, ptr [[E1]], i64 6
+; CHECK-NEXT: [[E4:%.*]] = getelementptr inbounds ptr, ptr [[E2]], <2 x i64> <i64 0, i64 1>
+; CHECK-NEXT: [[PI1:%.*]] = ptrtoint <2 x ptr> [[E4]] to <2 x i64>
; CHECK-NEXT: [[TMP0:%.*]] = lshr <2 x i64> [[PI1]], <i64 14, i64 14>
; CHECK-NEXT: [[SL1:%.*]] = and <2 x i64> [[TMP0]], <i64 1125899906842496, i64 1125899906842496>
-; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, i8* [[BASE:%.*]], i64 80
-; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, i8* [[E51]], <2 x i64> [[SL1]]
-; CHECK-NEXT: call void @blackhole(<2 x i8*> [[E6]])
+; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 80
+; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, ptr [[E51]], <2 x i64> [[SL1]]
+; CHECK-NEXT: call void @blackhole(<2 x ptr> [[E6]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
- %e1 = getelementptr inbounds i8*, i8** %in, i64 undef
- %e2 = getelementptr inbounds i8*, i8** %e1, i64 6
- %bc1 = bitcast i8** %e2 to <2 x i8*>*
- %e3 = getelementptr inbounds <2 x i8*>, <2 x i8*>* %bc1, i64 0, i64 0
- %e4 = getelementptr inbounds i8*, i8** %e3, <2 x i64> <i64 0, i64 1>
- %pi1 = ptrtoint <2 x i8**> %e4 to <2 x i64>
+ %e1 = getelementptr inbounds ptr, ptr %in, i64 undef
+ %e2 = getelementptr inbounds ptr, ptr %e1, i64 6
+ %e4 = getelementptr inbounds ptr, ptr %e2, <2 x i64> <i64 0, i64 1>
+ %pi1 = ptrtoint <2 x ptr> %e4 to <2 x i64>
%lr1 = lshr <2 x i64> %pi1, <i64 21, i64 21>
%sl1 = shl nuw nsw <2 x i64> %lr1, <i64 7, i64 7>
- %e5 = getelementptr inbounds i8, i8* %base, <2 x i64> %sl1
- %e6 = getelementptr inbounds i8, <2 x i8*> %e5, i64 80
- call void @blackhole(<2 x i8*> %e6)
+ %e5 = getelementptr inbounds i8, ptr %base, <2 x i64> %sl1
+ %e6 = getelementptr inbounds i8, <2 x ptr> %e5, i64 80
+ call void @blackhole(<2 x ptr> %e6)
br label %loop
}
-define void @PR37005_2(i8* %base, i8** %in) {
+define void @PR37005_2(ptr %base, ptr %in) {
; CHECK-LABEL: @PR37005_2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds i8*, i8** [[IN:%.*]], i64 undef
-; CHECK-NEXT: [[PI1:%.*]] = ptrtoint i8** [[E2]] to i64
+; CHECK-NEXT: [[E1:%.*]] = getelementptr inbounds ptr, ptr [[IN:%.*]], i64 undef
+; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds ptr, ptr [[E1]], i64 6
+; CHECK-NEXT: [[PI1:%.*]] = ptrtoint ptr [[E2]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[PI1]], 14
; CHECK-NEXT: [[SL1:%.*]] = and i64 [[TMP0]], 1125899906842496
-; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, i8* [[BASE:%.*]], <2 x i64> <i64 80, i64 60>
-; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, <2 x i8*> [[E51]], i64 [[SL1]]
-; CHECK-NEXT: call void @blackhole(<2 x i8*> [[E6]])
+; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], <2 x i64> <i64 80, i64 60>
+; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, <2 x ptr> [[E51]], i64 [[SL1]]
+; CHECK-NEXT: call void @blackhole(<2 x ptr> [[E6]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
- %e1 = getelementptr inbounds i8*, i8** %in, i64 undef
- %e2 = getelementptr inbounds i8*, i8** %e1, i64 6
- %pi1 = ptrtoint i8** %e2 to i64
+ %e1 = getelementptr inbounds ptr, ptr %in, i64 undef
+ %e2 = getelementptr inbounds ptr, ptr %e1, i64 6
+ %pi1 = ptrtoint ptr %e2 to i64
%lr1 = lshr i64 %pi1, 21
%sl1 = shl nuw nsw i64 %lr1, 7
- %e5 = getelementptr inbounds i8, i8* %base, i64 %sl1
- %e6 = getelementptr inbounds i8, i8* %e5, <2 x i64> <i64 80, i64 60>
- call void @blackhole(<2 x i8*> %e6)
+ %e5 = getelementptr inbounds i8, ptr %base, i64 %sl1
+ %e6 = getelementptr inbounds i8, ptr %e5, <2 x i64> <i64 80, i64 60>
+ call void @blackhole(<2 x ptr> %e6)
br label %loop
}
-define void @PR37005_3(<2 x i8*> %base, i8** %in) {
+define void @PR37005_3(<2 x ptr> %base, ptr %in) {
; CHECK-LABEL: @PR37005_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds i8*, i8** [[IN:%.*]], i64 undef
-; CHECK-NEXT: [[E4:%.*]] = getelementptr inbounds i8*, i8** [[E2]], <2 x i64> <i64 0, i64 1>
-; CHECK-NEXT: [[PI1:%.*]] = ptrtoint <2 x i8**> [[E4]] to <2 x i64>
+; CHECK-NEXT: [[E1:%.*]] = getelementptr inbounds ptr, ptr [[IN:%.*]], i64 undef
+; CHECK-NEXT: [[E2:%.*]] = getelementptr inbounds ptr, ptr [[E1]], i64 6
+; CHECK-NEXT: [[E4:%.*]] = getelementptr inbounds ptr, ptr [[E2]], <2 x i64> <i64 0, i64 1>
+; CHECK-NEXT: [[PI1:%.*]] = ptrtoint <2 x ptr> [[E4]] to <2 x i64>
; CHECK-NEXT: [[TMP0:%.*]] = lshr <2 x i64> [[PI1]], <i64 14, i64 14>
; CHECK-NEXT: [[SL1:%.*]] = and <2 x i64> [[TMP0]], <i64 1125899906842496, i64 1125899906842496>
-; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, <2 x i8*> [[BASE:%.*]], i64 80
-; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, <2 x i8*> [[E51]], <2 x i64> [[SL1]]
-; CHECK-NEXT: call void @blackhole(<2 x i8*> [[E6]])
+; CHECK-NEXT: [[E51:%.*]] = getelementptr inbounds i8, <2 x ptr> [[BASE:%.*]], i64 80
+; CHECK-NEXT: [[E6:%.*]] = getelementptr inbounds i8, <2 x ptr> [[E51]], <2 x i64> [[SL1]]
+; CHECK-NEXT: call void @blackhole(<2 x ptr> [[E6]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop: ; preds = %loop, %entry
- %e1 = getelementptr inbounds i8*, i8** %in, i64 undef
- %e2 = getelementptr inbounds i8*, i8** %e1, i64 6
- %bc1 = bitcast i8** %e2 to <2 x i8*>*
- %e3 = getelementptr inbounds <2 x i8*>, <2 x i8*>* %bc1, i64 0, i64 0
- %e4 = getelementptr inbounds i8*, i8** %e3, <2 x i64> <i64 0, i64 1>
- %pi1 = ptrtoint <2 x i8**> %e4 to <2 x i64>
+ %e1 = getelementptr inbounds ptr, ptr %in, i64 undef
+ %e2 = getelementptr inbounds ptr, ptr %e1, i64 6
+ %e4 = getelementptr inbounds ptr, ptr %e2, <2 x i64> <i64 0, i64 1>
+ %pi1 = ptrtoint <2 x ptr> %e4 to <2 x i64>
%lr1 = lshr <2 x i64> %pi1, <i64 21, i64 21>
%sl1 = shl nuw nsw <2 x i64> %lr1, <i64 7, i64 7>
- %e5 = getelementptr inbounds i8, <2 x i8*> %base, <2 x i64> %sl1
- %e6 = getelementptr inbounds i8, <2 x i8*> %e5, i64 80
- call void @blackhole(<2 x i8*> %e6)
+ %e5 = getelementptr inbounds i8, <2 x ptr> %base, <2 x i64> %sl1
+ %e6 = getelementptr inbounds i8, <2 x ptr> %e5, i64 80
+ call void @blackhole(<2 x ptr> %e6)
br label %loop
}
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[SL1:%.*]] = shl nuw nsw <2 x i64> [[V:%.*]], <i64 7, i64 7>
-; CHECK-NEXT: [[E6:%.*]] = getelementptr i8, i8* getelementptr (i8, i8* bitcast (void (<2 x i64>)* @PR51485 to i8*), i64 80), <2 x i64> [[SL1]]
-; CHECK-NEXT: call void @blackhole(<2 x i8*> [[E6]])
+; CHECK-NEXT: [[E6:%.*]] = getelementptr i8, ptr getelementptr (i8, ptr @PR51485, i64 80), <2 x i64> [[SL1]]
+; CHECK-NEXT: call void @blackhole(<2 x ptr> [[E6]])
; CHECK-NEXT: br label [[LOOP]]
;
entry:
loop: ; preds = %loop, %entry
%sl1 = shl nuw nsw <2 x i64> %v, <i64 7, i64 7>
- %e5 = getelementptr inbounds i8, i8* bitcast (void (<2 x i64>)* @PR51485 to i8*), <2 x i64> %sl1
- %e6 = getelementptr inbounds i8, <2 x i8*> %e5, i64 80
- call void @blackhole(<2 x i8*> %e6)
+ %e5 = getelementptr inbounds i8, ptr @PR51485, <2 x i64> %sl1
+ %e6 = getelementptr inbounds i8, <2 x ptr> %e5, i64 80
+ call void @blackhole(<2 x ptr> %e6)
br label %loop
}
; Avoid folding the GEP outside the loop to inside, and increasing loop
; instruction count.
-define float @gep_cross_loop(i64* %_arg_, float* %_arg_3, float %_arg_8) {
+define float @gep_cross_loop(ptr %_arg_, ptr %_arg_3, float %_arg_8) {
; CHECK-LABEL: @gep_cross_loop(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[I:%.*]] = load i64, i64* [[_ARG_:%.*]], align 8
-; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[_ARG_3:%.*]], i64 [[I]]
+; CHECK-NEXT: [[I:%.*]] = load i64, ptr [[_ARG_:%.*]], align 8
+; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, ptr [[_ARG_3:%.*]], i64 [[I]]
; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
; CHECK: for.cond.i:
; CHECK-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[ADD11_I:%.*]], [[FOR_BODY_I:%.*]] ]
; CHECK: for.cond.i.i.i.preheader:
; CHECK-NEXT: ret float [[SUM]]
; CHECK: for.body.i:
-; CHECK-NEXT: [[ARRAYIDX_I84_I:%.*]] = getelementptr inbounds float, float* [[ADD_PTR]], i64 [[IDX]]
-; CHECK-NEXT: [[I1:%.*]] = load float, float* [[ARRAYIDX_I84_I]], align 4
+; CHECK-NEXT: [[ARRAYIDX_I84_I:%.*]] = getelementptr inbounds float, ptr [[ADD_PTR]], i64 [[IDX]]
+; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[ARRAYIDX_I84_I]], align 4
; CHECK-NEXT: [[ADD_I]] = fadd fast float [[SUM]], [[I1]]
; CHECK-NEXT: [[ADD11_I]] = add nuw nsw i64 [[IDX]], 1
; CHECK-NEXT: br label [[FOR_COND_I]]
;
entry:
- %i = load i64, i64* %_arg_, align 8
- %add.ptr = getelementptr inbounds float, float* %_arg_3, i64 %i
+ %i = load i64, ptr %_arg_, align 8
+ %add.ptr = getelementptr inbounds float, ptr %_arg_3, i64 %i
br label %for.cond.i
for.cond.i: ; preds = %for.body.i, %entry
ret float %sum
for.body.i: ; preds = %for.cond.i
- %arrayidx.i84.i = getelementptr inbounds float, float* %add.ptr, i64 %idx
- %i1 = load float, float* %arrayidx.i84.i, align 4
+ %arrayidx.i84.i = getelementptr inbounds float, ptr %add.ptr, i64 %idx
+ %i1 = load float, ptr %arrayidx.i84.i, align 4
%add.i = fadd fast float %sum, %i1
%add11.i = add nsw i64 %idx, 1
br label %for.cond.i
}
-declare void @use(i8*)
+declare void @use(ptr)
-define void @only_one_inbounds(i8* %ptr, i1 %c, i32 noundef %arg1, i32 noundef %arg2) {
+define void @only_one_inbounds(ptr %ptr, i1 %c, i32 noundef %arg1, i32 noundef %arg2) {
; CHECK-LABEL: @only_one_inbounds(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ARG2_EXT:%.*]] = zext i32 [[ARG2:%.*]] to i64
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[ARG1_EXT:%.*]] = zext i32 [[ARG1:%.*]] to i64
-; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 [[ARG2_EXT]]
-; CHECK-NEXT: [[PTR3:%.*]] = getelementptr i8, i8* [[PTR21]], i64 [[ARG1_EXT]]
-; CHECK-NEXT: call void @use(i8* [[PTR3]])
+; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 [[ARG2_EXT]]
+; CHECK-NEXT: [[PTR3:%.*]] = getelementptr i8, ptr [[PTR21]], i64 [[ARG1_EXT]]
+; CHECK-NEXT: call void @use(ptr [[PTR3]])
; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
loop: ; preds = %loop, %entry
%arg1.ext = zext i32 %arg1 to i64
- %ptr2 = getelementptr inbounds i8, i8* %ptr, i64 %arg1.ext
- %ptr3 = getelementptr i8, i8* %ptr2, i64 %arg2.ext
- call void @use(i8* %ptr3)
+ %ptr2 = getelementptr inbounds i8, ptr %ptr, i64 %arg1.ext
+ %ptr3 = getelementptr i8, ptr %ptr2, i64 %arg2.ext
+ call void @use(ptr %ptr3)
br i1 %c, label %loop, label %exit
exit: ; preds = %loop
ret void
}
-define void @both_inbounds_one_neg(i8* %ptr, i1 %c, i32 noundef %arg) {
+define void @both_inbounds_one_neg(ptr %ptr, i1 %c, i32 noundef %arg) {
; CHECK-LABEL: @both_inbounds_one_neg(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[ARG_EXT:%.*]] = zext i32 [[ARG:%.*]] to i64
-; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 -1
-; CHECK-NEXT: [[PTR3:%.*]] = getelementptr i8, i8* [[PTR21]], i64 [[ARG_EXT]]
-; CHECK-NEXT: call void @use(i8* [[PTR3]])
+; CHECK-NEXT: [[PTR21:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 -1
+; CHECK-NEXT: [[PTR3:%.*]] = getelementptr i8, ptr [[PTR21]], i64 [[ARG_EXT]]
+; CHECK-NEXT: call void @use(ptr [[PTR3]])
; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
loop: ; preds = %loop, %entry
%arg.ext = zext i32 %arg to i64
- %ptr2 = getelementptr inbounds i8, i8* %ptr, i64 %arg.ext
- %ptr3 = getelementptr inbounds i8, i8* %ptr2, i64 -1
- call void @use(i8* %ptr3)
+ %ptr2 = getelementptr inbounds i8, ptr %ptr, i64 %arg.ext
+ %ptr3 = getelementptr inbounds i8, ptr %ptr2, i64 -1
+ call void @use(ptr %ptr3)
br i1 %c, label %loop, label %exit
exit: ; preds = %loop
ret void
}
-define void @both_inbounds_pos(i8* %ptr, i1 %c, i32 noundef %arg) {
+define void @both_inbounds_pos(ptr %ptr, i1 %c, i32 noundef %arg) {
; CHECK-LABEL: @both_inbounds_pos(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[ARG_EXT:%.*]] = zext i32 [[ARG:%.*]] to i64
-; CHECK-NEXT: [[PTR21:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 1
-; CHECK-NEXT: [[PTR3:%.*]] = getelementptr inbounds i8, i8* [[PTR21]], i64 [[ARG_EXT]]
-; CHECK-NEXT: call void @use(i8* nonnull [[PTR3]])
+; CHECK-NEXT: [[PTR21:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 1
+; CHECK-NEXT: [[PTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR21]], i64 [[ARG_EXT]]
+; CHECK-NEXT: call void @use(ptr nonnull [[PTR3]])
; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
loop: ; preds = %loop, %entry
%arg.ext = zext i32 %arg to i64
- %ptr2 = getelementptr inbounds i8, i8* %ptr, i64 %arg.ext
- %ptr3 = getelementptr inbounds i8, i8* %ptr2, i64 1
- call void @use(i8* %ptr3)
+ %ptr2 = getelementptr inbounds i8, ptr %ptr, i64 %arg.ext
+ %ptr3 = getelementptr inbounds i8, ptr %ptr2, i64 1
+ call void @use(ptr %ptr3)
br i1 %c, label %loop, label %exit
exit: ; preds = %loop
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
-define void @test1(float* %a, float* readnone %a_end, i32* %b.i) {
+define void @test1(ptr %a, ptr readnone %a_end, ptr %b.i) {
; CHECK-LABEL: define void @test1
-; CHECK-SAME: (float* [[A:%.*]], float* readnone [[A_END:%.*]], i32* [[B_I:%.*]]) {
+; CHECK-SAME: (ptr [[A:%.*]], ptr readnone [[A_END:%.*]], ptr [[B_I:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ult float* [[A]], [[A_END]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A]], [[A_END]]
; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.preheader:
-; CHECK-NEXT: [[B_I_PTR:%.*]] = bitcast i32* [[B_I]] to float*
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi float* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ]
-; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi float* [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_I_PTR]], [[FOR_BODY_PREHEADER]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[B_ADDR_02_PTR]], align 4
+; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi ptr [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_I]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR_02_PTR]], align 4
; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[TMP1]], 4.200000e+01
-; CHECK-NEXT: store float [[MUL_I]], float* [[A_ADDR_03]], align 4
-; CHECK-NEXT: [[ADD]] = getelementptr inbounds float, float* [[B_ADDR_02_PTR]], i64 1
-; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds float, float* [[A_ADDR_03]], i64 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult float* [[INCDEC_PTR]], [[A_END]]
+; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4
+; CHECK-NEXT: [[ADD]] = getelementptr inbounds float, ptr [[B_ADDR_02_PTR]], i64 1
+; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds float, ptr [[A_ADDR_03]], i64 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: ret void
;
entry:
- %cmp1 = icmp ult float* %a, %a_end
+ %cmp1 = icmp ult ptr %a, %a_end
br i1 %cmp1, label %for.body.preheader, label %for.end
for.body.preheader: ; preds = %entry
- %b = ptrtoint i32 * %b.i to i64
+ %b = ptrtoint ptr %b.i to i64
br label %for.body
for.body: ; preds = %for.body, %for.body.preheader
- %a.addr.03 = phi float* [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ]
+ %a.addr.03 = phi ptr [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ]
%b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ]
- %tmp = inttoptr i64 %b.addr.02 to float*
- %tmp1 = load float, float* %tmp, align 4
+ %tmp = inttoptr i64 %b.addr.02 to ptr
+ %tmp1 = load float, ptr %tmp, align 4
%mul.i = fmul float %tmp1, 4.200000e+01
- store float %mul.i, float* %a.addr.03, align 4
- %add = getelementptr inbounds float, float* %tmp, i64 1
- %add.int = ptrtoint float* %add to i64
- %incdec.ptr = getelementptr inbounds float, float* %a.addr.03, i64 1
- %cmp = icmp ult float* %incdec.ptr, %a_end
+ store float %mul.i, ptr %a.addr.03, align 4
+ %add = getelementptr inbounds float, ptr %tmp, i64 1
+ %add.int = ptrtoint ptr %add to i64
+ %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1
+ %cmp = icmp ult ptr %incdec.ptr, %a_end
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body, %entry
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; Test to check that instcombine doesn't drop the address space when optimizing
; memset.
%struct.Moves = type { [9 x i8], i8, i8, i8, [5 x i8] }
-define i32 @test(%struct.Moves addrspace(1)* nocapture %moves) {
+define i32 @test(ptr addrspace(1) nocapture %moves) {
; CHECK-LABEL: define i32 @test
-; CHECK-SAME: ([[STRUCT_MOVES:%.*]] addrspace(1)* nocapture [[MOVES:%.*]]) {
+; CHECK-SAME: (ptr addrspace(1) nocapture [[MOVES:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_MOVES]], [[STRUCT_MOVES]] addrspace(1)* [[MOVES]], i64 1, i32 0, i64 9
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8 addrspace(1)* [[GEP]] to i64 addrspace(1)*
-; CHECK-NEXT: store i64 0, i64 addrspace(1)* [[TMP0]], align 1
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_MOVES:%.*]], ptr addrspace(1) [[MOVES]], i64 1, i32 0, i64 9
+; CHECK-NEXT: store i64 0, ptr addrspace(1) [[GEP]], align 1
; CHECK-NEXT: ret i32 0
;
entry:
- %gep = getelementptr inbounds %struct.Moves, %struct.Moves addrspace(1)* %moves, i32 1, i32 0, i32 9
- call void @llvm.memset.p1i8.i64(i8 addrspace(1)* %gep, i8 0, i64 8, i1 false)
+ %gep = getelementptr inbounds %struct.Moves, ptr addrspace(1) %moves, i32 1, i32 0, i32 9
+ call void @llvm.memset.p1.i64(ptr addrspace(1) %gep, i8 0, i64 8, i1 false)
ret i32 0
}
-declare void @llvm.memset.p1i8.i64(i8addrspace(1)* nocapture, i8, i64, i1) nounwind
+declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture, i8, i64, i1) nounwind