; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
-define internal i32 @deref(i32* %x) nounwind {
+define internal i32 @deref(ptr %x) nounwind {
; CHECK-LABEL: define {{[^@]+}}@deref
; CHECK-SAME: (i32 [[X_0_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[X_0_VAL]]
;
entry:
- %temp2 = load i32, i32* %x, align 4
+ %temp2 = load i32, ptr %x, align 4
ret i32 %temp2
}
; CHECK-SAME: (i32 [[X:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
-; CHECK-NEXT: [[X_ADDR_VAL:%.*]] = load i32, i32* [[X_ADDR]], align 4
+; CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
+; CHECK-NEXT: [[X_ADDR_VAL:%.*]] = load i32, ptr [[X_ADDR]], align 4
; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @deref(i32 [[X_ADDR_VAL]])
; CHECK-NEXT: ret i32 [[TEMP1]]
;
entry:
%x_addr = alloca i32
- store i32 %x, i32* %x_addr, align 4
- %temp1 = call i32 @deref( i32* %x_addr ) nounwind
+ store i32 %x, ptr %x_addr, align 4
+ %temp1 = call i32 @deref( ptr %x_addr ) nounwind
ret i32 %temp1
}
; This test tries to convince CHECK about promoting the load from %A + 2,
; because there is a load of %A in the entry block
-define internal i32 @callee(i1 %C, i32* %A) {
+define internal i32 @callee(i1 %C, ptr %A) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[A:%.*]]) {
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4
+; CHECK-NEXT: [[A_0:%.*]] = load i32, ptr [[A]], align 4
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CHECK: T:
; CHECK-NEXT: ret i32 [[A_0]]
; CHECK: F:
-; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2
-; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4
+; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, ptr [[A]], i32 2
+; CHECK-NEXT: [[R:%.*]] = load i32, ptr [[A_2]], align 4
; CHECK-NEXT: ret i32 [[R]]
;
entry:
; Unconditonally load the element at %A
- %A.0 = load i32, i32* %A
+ %A.0 = load i32, ptr %A
br i1 %C, label %T, label %F
T:
F:
; Load the element at offset two from %A. This should not be promoted!
- %A.2 = getelementptr i32, i32* %A, i32 2
- %R = load i32, i32* %A.2
+ %A.2 = getelementptr i32, ptr %A, i32 2
+ %R = load i32, ptr %A.2
ret i32 %R
}
define i32 @foo() {
; CHECK-LABEL: define {{[^@]+}}@foo() {
-; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* null)
+; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, ptr null)
; CHECK-NEXT: ret i32 [[X]]
;
- %X = call i32 @callee(i1 false, i32* null) ; <i32> [#uses=1]
+ %X = call i32 @callee(i1 false, ptr null) ; <i32> [#uses=1]
ret i32 %X
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt < %s -passes=inline,argpromotion -disable-output
-define internal fastcc i32 @hash(i32* %ts, i32 %mod) nounwind {
+define internal fastcc i32 @hash(ptr %ts, i32 %mod) nounwind {
entry:
unreachable
}
-define void @encode(i32* %m, i32* %ts, i32* %new) nounwind {
+define void @encode(ptr %m, ptr %ts, ptr %new) nounwind {
entry:
- %0 = call fastcc i32 @hash( i32* %ts, i32 0 ) nounwind ; <i32> [#uses=0]
+ %0 = call fastcc i32 @hash( ptr %ts, i32 0 ) nounwind ; <i32> [#uses=0]
unreachable
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt < %s -passes=argpromotion -disable-output
-define internal fastcc i32 @term_SharingList(i32* %Term, i32* %List) nounwind {
+define internal fastcc i32 @term_SharingList(ptr %Term, ptr %List) nounwind {
entry:
br i1 false, label %bb, label %bb5
bb: ; preds = %entry
- %0 = call fastcc i32 @term_SharingList( i32* null, i32* %List ) nounwind ; <i32> [#uses=0]
+ %0 = call fastcc i32 @term_SharingList( ptr null, ptr %List ) nounwind ; <i32> [#uses=0]
unreachable
bb5: ; preds = %entry
ret i32 0
}
-define i32 @term_Sharing(i32* %Term) nounwind {
+define i32 @term_Sharing(ptr %Term) nounwind {
entry:
br i1 false, label %bb.i, label %bb14
bb.i: ; preds = %entry
- %0 = call fastcc i32 @term_SharingList( i32* null, i32* null ) nounwind ; <i32> [#uses=0]
+ %0 = call fastcc i32 @term_SharingList( ptr null, ptr null ) nounwind ; <i32> [#uses=0]
ret i32 1
bb14: ; preds = %entry
target triple = "x86_64-unknown-linux-gnu"
-define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 {
+define internal fastcc void @no_promote_avx2(ptr %arg, ptr readonly %arg1) #0 {
; CHECK-LABEL: define {{[^@]+}}@no_promote_avx2
-; CHECK-SAME: (<4 x i64>* [[ARG:%.*]], <4 x i64>* readonly [[ARG1:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr readonly [[ARG1:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]]
-; CHECK-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]]
+; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, ptr [[ARG1]]
+; CHECK-NEXT: store <4 x i64> [[TMP]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <4 x i64>, <4 x i64>* %arg1
- store <4 x i64> %tmp, <4 x i64>* %arg
+ %tmp = load <4 x i64>, ptr %arg1
+ store <4 x i64> %tmp, ptr %arg
ret void
}
-define void @no_promote(<4 x i64>* %arg) #1 {
+define void @no_promote(ptr %arg) #1 {
; CHECK-LABEL: define {{[^@]+}}@no_promote
-; CHECK-SAME: (<4 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* [[TMP2]], <4 x i64>* [[TMP]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: call fastcc void @no_promote_avx2(ptr [[TMP2]], ptr [[TMP]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <4 x i64>, align 32
%tmp2 = alloca <4 x i64>, align 32
- %tmp3 = bitcast <4 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @no_promote_avx2(<4 x i64>* %tmp2, <4 x i64>* %tmp)
- %tmp4 = load <4 x i64>, <4 x i64>* %tmp2, align 32
- store <4 x i64> %tmp4, <4 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @no_promote_avx2(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <4 x i64>, ptr %tmp2, align 32
+ store <4 x i64> %tmp4, ptr %arg, align 2
ret void
}
-define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 {
+define internal fastcc void @promote_avx2(ptr %arg, ptr readonly %arg1) #0 {
; CHECK-LABEL: define {{[^@]+}}@promote_avx2
-; CHECK-SAME: (<4 x i64>* [[ARG:%.*]], <4 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <4 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <4 x i64> [[ARG1_VAL]], <4 x i64>* [[ARG]]
+; CHECK-NEXT: store <4 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <4 x i64>, <4 x i64>* %arg1
- store <4 x i64> %tmp, <4 x i64>* %arg
+ %tmp = load <4 x i64>, ptr %arg1
+ store <4 x i64> %tmp, ptr %arg
ret void
}
-define void @promote(<4 x i64>* %arg) #0 {
+define void @promote(ptr %arg) #0 {
; CHECK-LABEL: define {{[^@]+}}@promote
-; CHECK-SAME: (<4 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <4 x i64>, <4 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @promote_avx2(<4 x i64>* [[TMP2]], <4 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <4 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @promote_avx2(ptr [[TMP2]], <4 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <4 x i64>, align 32
%tmp2 = alloca <4 x i64>, align 32
- %tmp3 = bitcast <4 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @promote_avx2(<4 x i64>* %tmp2, <4 x i64>* %tmp)
- %tmp4 = load <4 x i64>, <4 x i64>* %tmp2, align 32
- store <4 x i64> %tmp4, <4 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @promote_avx2(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <4 x i64>, ptr %tmp2, align 32
+ store <4 x i64> %tmp4, ptr %arg, align 2
ret void
}
; Function Attrs: argmemonly nounwind
-declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) #2
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1) #2
attributes #0 = { inlinehint norecurse nounwind uwtable "target-features"="+avx2" }
attributes #1 = { nounwind uwtable }
target triple = "x86_64-unknown-linux-gnu"
; This should promote
-define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 {
+define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg, ptr readonly %arg1) #0 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg) #0 {
+define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg) #0 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should promote
-define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 {
+define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg, ptr readonly %arg1) #1 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #1 {
+define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg) #1 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should promote
-define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 {
+define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg, ptr readonly %arg1) #1 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg) #0 {
+define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg) #0 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should promote
-define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 {
+define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg, ptr readonly %arg1) #0 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg) #1 {
+define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg) #1 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should not promote
-define internal fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 {
+define internal fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %arg, ptr readonly %arg1) #1 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64>* readonly [[ARG1:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr readonly [[ARG1:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]]
-; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, ptr [[ARG1]]
+; CHECK-NEXT: store <8 x i64> [[TMP]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #2 {
+define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %arg) #2 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* [[TMP2]], <8 x i64>* [[TMP]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr [[TMP2]], ptr [[TMP]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should not promote
-define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #2 {
+define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %arg, ptr readonly %arg1) #2 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64>* readonly [[ARG1:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr readonly [[ARG1:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]]
-; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, ptr [[ARG1]]
+; CHECK-NEXT: store <8 x i64> [[TMP]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg) #1 {
+define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %arg) #1 {
; CHECK-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* [[TMP2]], <8 x i64>* [[TMP]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr [[TMP2]], ptr [[TMP]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should promote
-define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #3 {
+define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg, ptr readonly %arg1) #3 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg) #4 {
+define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg) #4 {
; CHECK-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; This should promote
-define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #4 {
+define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg, ptr readonly %arg1) #4 {
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
; CHECK-NEXT: bb:
-; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], <8 x i64>* [[ARG]]
+; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
; CHECK-NEXT: ret void
;
bb:
- %tmp = load <8 x i64>, <8 x i64>* %arg1
- store <8 x i64> %tmp, <8 x i64>* %arg
+ %tmp = load <8 x i64>, ptr %arg1
+ store <8 x i64> %tmp, ptr %arg
ret void
}
-define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg) #3 {
+define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg) #3 {
; CHECK-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
-; CHECK-SAME: (<8 x i64>* [[ARG:%.*]])
+; CHECK-SAME: (ptr [[ARG:%.*]])
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP3]], i8 0, i64 32, i1 false)
-; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]]
-; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* [[TMP2]], <8 x i64> [[TMP_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 32
-; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
+; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
+; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
+; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
+; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; CHECK-NEXT: ret void
;
bb:
%tmp = alloca <8 x i64>, align 32
%tmp2 = alloca <8 x i64>, align 32
- %tmp3 = bitcast <8 x i64>* %tmp to i8*
- call void @llvm.memset.p0i8.i64(i8* align 32 %tmp3, i8 0, i64 32, i1 false)
- call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %tmp2, <8 x i64>* %tmp)
- %tmp4 = load <8 x i64>, <8 x i64>* %tmp2, align 32
- store <8 x i64> %tmp4, <8 x i64>* %arg, align 2
+ call void @llvm.memset.p0.i64(ptr align 32 %tmp, i8 0, i64 32, i1 false)
+ call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %tmp2, ptr %tmp)
+ %tmp4 = load <8 x i64>, ptr %tmp2, align 32
+ store <8 x i64> %tmp4, ptr %arg, align 2
ret void
}
; If the arguments are scalar, its ok to promote.
-define internal i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(i32* %X, i32* %Y) #2 {
+define internal i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %X, ptr %Y) #2 {
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
; CHECK-SAME: (i32 [[X_VAL:%.*]], i32 [[Y_VAL:%.*]])
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_VAL]], [[Y_VAL]]
; CHECK-NEXT: ret i32 [[C]]
;
- %A = load i32, i32* %X
- %B = load i32, i32* %Y
+ %A = load i32, ptr %X
+ %B = load i32, ptr %Y
%C = add i32 %A, %B
ret i32 %C
}
-define i32 @scalar_avx512_legal256_prefer256_call_avx512_legal512_prefer256(i32* %B) #2 {
+define i32 @scalar_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %B) #2 {
; CHECK-LABEL: define {{[^@]+}}@scalar_avx512_legal256_prefer256_call_avx512_legal512_prefer256
-; CHECK-SAME: (i32* [[B:%.*]])
+; CHECK-SAME: (ptr [[B:%.*]])
; CHECK-NEXT: [[A:%.*]] = alloca i32
-; CHECK-NEXT: store i32 1, i32* [[A]]
-; CHECK-NEXT: [[A_VAL:%.*]] = load i32, i32* [[A]]
-; CHECK-NEXT: [[B_VAL:%.*]] = load i32, i32* [[B]]
+; CHECK-NEXT: store i32 1, ptr [[A]]
+; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]]
+; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]]
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(i32 [[A_VAL]], i32 [[B_VAL]])
; CHECK-NEXT: ret i32 [[C]]
;
%A = alloca i32
- store i32 1, i32* %A
- %C = call i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(i32* %A, i32* %B)
+ store i32 1, ptr %A
+ %C = call i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %A, ptr %B)
ret i32 %C
}
; If the arguments are scalar, its ok to promote.
-define internal i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(i32* %X, i32* %Y) #2 {
+define internal i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %X, ptr %Y) #2 {
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
; CHECK-SAME: (i32 [[X_VAL:%.*]], i32 [[Y_VAL:%.*]])
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_VAL]], [[Y_VAL]]
; CHECK-NEXT: ret i32 [[C]]
;
- %A = load i32, i32* %X
- %B = load i32, i32* %Y
+ %A = load i32, ptr %X
+ %B = load i32, ptr %Y
%C = add i32 %A, %B
ret i32 %C
}
-define i32 @scalar_avx512_legal512_prefer256_call_avx512_legal256_prefer256(i32* %B) #2 {
+define i32 @scalar_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %B) #2 {
; CHECK-LABEL: define {{[^@]+}}@scalar_avx512_legal512_prefer256_call_avx512_legal256_prefer256
-; CHECK-SAME: (i32* [[B:%.*]])
+; CHECK-SAME: (ptr [[B:%.*]])
; CHECK-NEXT: [[A:%.*]] = alloca i32
-; CHECK-NEXT: store i32 1, i32* [[A]]
-; CHECK-NEXT: [[A_VAL:%.*]] = load i32, i32* [[A]]
-; CHECK-NEXT: [[B_VAL:%.*]] = load i32, i32* [[B]]
+; CHECK-NEXT: store i32 1, ptr [[A]]
+; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]]
+; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]]
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(i32 [[A_VAL]], i32 [[B_VAL]])
; CHECK-NEXT: ret i32 [[C]]
;
%A = alloca i32
- store i32 1, i32* %A
- %C = call i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(i32* %A, i32* %B)
+ store i32 1, ptr %A
+ %C = call i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %A, ptr %B)
ret i32 %C
}
; Function Attrs: argmemonly nounwind
-declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) #5
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1) #5
attributes #0 = { inlinehint norecurse nounwind uwtable "target-features"="+avx512vl" "min-legal-vector-width"="512" "prefer-vector-width"="512" }
attributes #1 = { inlinehint norecurse nounwind uwtable "target-features"="+avx512vl" "min-legal-vector-width"="512" "prefer-vector-width"="256" }
%struct.a = type { i8 }
-define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca(<{ %struct.a }>)) {
+define internal x86_thiscallcc void @internalfun(ptr %this, <{ %struct.a }>* inalloca(<{ %struct.a }>)) {
; ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun
-; ARGPROMOTION-SAME: (%struct.a* [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca(<{ [[STRUCT_A]] }>) [[TMP0:%.*]]) {
+; ARGPROMOTION-SAME: (ptr [[THIS:%.*]], ptr inalloca(<{ [[STRUCT_A:%.*]] }>) [[TMP0:%.*]]) {
; ARGPROMOTION-NEXT: entry:
-; ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
+; ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, ptr [[TMP0]], i32 0, i32 0
; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4
-; ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
-; ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]])
-; ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
+; ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, ptr [[ARGMEM]], i32 0, i32 0
+; ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc ptr @copy_ctor(ptr [[TMP1]], ptr dereferenceable(1) [[A]])
+; ARGPROMOTION-NEXT: call void @ext(ptr inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
; ARGPROMOTION-NEXT: ret void
;
; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun
-; GLOBALOPT_ARGPROMOTION-SAME: (<{ [[STRUCT_A:%.*]] }>* [[TMP0:%.*]]) unnamed_addr {
+; GLOBALOPT_ARGPROMOTION-SAME: (ptr [[TMP0:%.*]]) unnamed_addr {
; GLOBALOPT_ARGPROMOTION-NEXT: entry:
-; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
+; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A:%.*]] }>, ptr [[TMP0]], i32 0, i32 0
; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4
-; GLOBALOPT_ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
-; GLOBALOPT_ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]])
-; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
+; GLOBALOPT_ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, ptr [[ARGMEM]], i32 0, i32 0
+; GLOBALOPT_ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc ptr @copy_ctor(ptr [[TMP1]], ptr dereferenceable(1) [[A]])
+; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(ptr inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
; GLOBALOPT_ARGPROMOTION-NEXT: ret void
;
entry:
%a = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %0, i32 0, i32 0
%argmem = alloca inalloca <{ %struct.a }>, align 4
%1 = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %argmem, i32 0, i32 0
- %call = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* %1, %struct.a* dereferenceable(1) %a)
+ %call = call x86_thiscallcc ptr @copy_ctor(ptr %1, ptr dereferenceable(1) %a)
call void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem)
ret void
}
; This is here to ensure @internalfun is live.
-define void @exportedfun(%struct.a* %a) {
+define void @exportedfun(ptr %a) {
; ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun
-; ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) {
-; ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave()
+; ARGPROMOTION-SAME: (ptr [[A:%.*]]) {
+; ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call ptr @llvm.stacksave()
; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4
-; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(%struct.a* [[A]], <{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
-; ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]])
+; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(ptr [[A]], ptr inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
+; ARGPROMOTION-NEXT: call void @llvm.stackrestore(ptr [[INALLOCA_SAVE]])
; ARGPROMOTION-NEXT: ret void
;
; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun
-; GLOBALOPT_ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) local_unnamed_addr {
-; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave()
+; GLOBALOPT_ARGPROMOTION-SAME: (ptr [[A:%.*]]) local_unnamed_addr {
+; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call ptr @llvm.stacksave()
; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4
-; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(<{ [[STRUCT_A]] }>* [[ARGMEM]])
-; GLOBALOPT_ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]])
+; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(ptr [[ARGMEM]])
+; GLOBALOPT_ARGPROMOTION-NEXT: call void @llvm.stackrestore(ptr [[INALLOCA_SAVE]])
; GLOBALOPT_ARGPROMOTION-NEXT: ret void
;
- %inalloca.save = tail call i8* @llvm.stacksave()
+ %inalloca.save = tail call ptr @llvm.stacksave()
%argmem = alloca inalloca <{ %struct.a }>, align 4
- call x86_thiscallcc void @internalfun(%struct.a* %a, <{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem)
- call void @llvm.stackrestore(i8* %inalloca.save)
+ call x86_thiscallcc void @internalfun(ptr %a, <{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem)
+ call void @llvm.stackrestore(ptr %inalloca.save)
ret void
}
-declare x86_thiscallcc %struct.a* @copy_ctor(%struct.a* returned, %struct.a* dereferenceable(1))
+declare x86_thiscallcc ptr @copy_ctor(ptr returned, ptr dereferenceable(1))
declare void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>))
-declare i8* @llvm.stacksave()
-declare void @llvm.stackrestore(i8*)
+declare ptr @llvm.stacksave()
+declare void @llvm.stackrestore(ptr)
%T = type { i32, i32, i32, i32 }
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
-define internal i32 @test(%T* %p) {
+define internal i32 @test(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: (i32 [[P_12_VAL:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[V]]
;
entry:
- %a.gep = getelementptr %T, %T* %p, i64 0, i32 3
- %b.gep = getelementptr %T, %T* %p, i64 0, i32 2
- %a = load i32, i32* %a.gep
+ %a.gep = getelementptr %T, ptr %p, i64 0, i32 3
+ %b.gep = getelementptr %T, ptr %p, i64 0, i32 2
+ %a = load i32, ptr %a.gep
%v = add i32 %a, 10
ret i32 %v
}
define i32 @caller() {
; CHECK-LABEL: define {{[^@]+}}@caller() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3
-; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* [[TMP0]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr @G, i64 12
+; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_VAL]])
; CHECK-NEXT: ret i32 [[V]]
;
entry:
- %v = call i32 @test(%T* @G)
+ %v = call i32 @test(ptr @G)
ret i32 %v
}
%T = type { i32, i32, i32, i32 }
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
-define internal i32 @test(%T* %p) {
+define internal i32 @test(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: (i32 [[P_8_VAL:%.*]], i32 [[P_12_VAL:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[V]]
;
entry:
- %a.gep = getelementptr %T, %T* %p, i64 0, i32 3
- %b.gep = getelementptr %T, %T* %p, i64 0, i32 2
- %a = load i32, i32* %a.gep
- %b = load i32, i32* %b.gep
+ %a.gep = getelementptr %T, ptr %p, i64 0, i32 3
+ %b.gep = getelementptr %T, ptr %p, i64 0, i32 2
+ %a = load i32, ptr %a.gep
+ %b = load i32, ptr %b.gep
%v = add i32 %a, %b
ret i32 %v
}
define i32 @caller() {
; CHECK-LABEL: define {{[^@]+}}@caller() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 2
-; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* [[TMP0]], align 4
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 3
-; CHECK-NEXT: [[G_VAL1:%.*]] = load i32, i32* [[TMP1]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr @G, i64 8
+; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr @G, i64 12
+; CHECK-NEXT: [[G_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_VAL]], i32 [[G_VAL1]])
; CHECK-NEXT: ret i32 [[V]]
;
entry:
- %v = call i32 @test(%T* @G)
+ %v = call i32 @test(ptr @G)
ret i32 %v
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
-define internal i32 @callee_must_exec(i32* %p) {
+define internal i32 @callee_must_exec(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_must_exec
; CHECK-SAME: (i32 [[P_0_VAL:%.*]]) {
; CHECK-NEXT: ret i32 [[P_0_VAL]]
;
- %x = load i32, i32* %p, align 16
+ %x = load i32, ptr %p, align 16
ret i32 %x
}
-define void @caller_must_exec(i32* %p) {
+define void @caller_must_exec(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_must_exec
-; CHECK-SAME: (i32* [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_must_exec(i32 [[P_VAL]])
; CHECK-NEXT: ret void
;
- call i32 @callee_must_exec(i32* %p)
+ call i32 @callee_must_exec(ptr %p)
ret void
}
-define internal i32 @callee_guaranteed_aligned_1(i1 %c, i32* %p) {
+define internal i32 @callee_guaranteed_aligned_1(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_1
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
br i1 %c, label %if, label %else
if:
- %x = load i32, i32* %p, align 16
+ %x = load i32, ptr %p, align 16
ret i32 %x
else:
ret i32 -1
}
-define void @caller_guaranteed_aligned_1(i1 %c, i32* align 16 dereferenceable(4) %p) {
+define void @caller_guaranteed_aligned_1(i1 %c, ptr align 16 dereferenceable(4) %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_1
-; CHECK-SAME: (i1 [[C:%.*]], i32* align 16 dereferenceable(4) [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-SAME: (i1 [[C:%.*]], ptr align 16 dereferenceable(4) [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_1(i1 [[C]], i32 [[P_VAL]])
; CHECK-NEXT: ret void
;
- call i32 @callee_guaranteed_aligned_1(i1 %c, i32* %p)
+ call i32 @callee_guaranteed_aligned_1(i1 %c, ptr %p)
ret void
}
-define internal i32 @callee_guaranteed_aligned_2(i1 %c, i32* align 16 dereferenceable(4) %p) {
+define internal i32 @callee_guaranteed_aligned_2(i1 %c, ptr align 16 dereferenceable(4) %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_2
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
br i1 %c, label %if, label %else
if:
- %x = load i32, i32* %p, align 16
+ %x = load i32, ptr %p, align 16
ret i32 %x
else:
ret i32 -1
}
-define void @caller_guaranteed_aligned_2(i1 %c, i32* %p) {
+define void @caller_guaranteed_aligned_2(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_2
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_2(i1 [[C]], i32 [[P_VAL]])
; CHECK-NEXT: ret void
;
- call i32 @callee_guaranteed_aligned_2(i1 %c, i32* %p)
+ call i32 @callee_guaranteed_aligned_2(i1 %c, ptr %p)
ret void
}
; We have seen the offset before but with a lower alignment
-define internal i32 @callee_guaranteed_aligned_3(i1 %c, i32* align 16 dereferenceable(4) %p) {
+define internal i32 @callee_guaranteed_aligned_3(i1 %c, ptr align 16 dereferenceable(4) %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_3
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
- %x = load i32, i32* %p, align 8
+ %x = load i32, ptr %p, align 8
br i1 %c, label %if, label %else
if:
- %y = load i32, i32* %p, align 16
+ %y = load i32, ptr %p, align 16
ret i32 %y
else:
ret i32 -1
}
-define void @caller_guaranteed_aligned_3(i1 %c, i32* %p) {
+define void @caller_guaranteed_aligned_3(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_3
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_3(i1 [[C]], i32 [[P_VAL]])
; CHECK-NEXT: ret void
;
- call i32 @callee_guaranteed_aligned_3(i1 %c, i32* %p)
+ call i32 @callee_guaranteed_aligned_3(i1 %c, ptr %p)
ret void
}
; We have seen the offset before but with a lower alignment, the guaranteed
; alignment is insufficient and the argument should not be promoted.
-define internal i32 @callee_guaranteed_insufficient_aligned(i1 %c, i32* align 8 dereferenceable(4) %p) {
+define internal i32 @callee_guaranteed_insufficient_aligned(i1 %c, ptr align 8 dereferenceable(4) %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_insufficient_aligned
-; CHECK-SAME: (i1 [[C:%.*]], i32* align 8 dereferenceable(4) [[P:%.*]]) {
-; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 8
+; CHECK-SAME: (i1 [[C:%.*]], ptr align 8 dereferenceable(4) [[P:%.*]]) {
+; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 8
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
-; CHECK-NEXT: [[Y:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-NEXT: [[Y:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: ret i32 [[Y]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
- %x = load i32, i32* %p, align 8
+ %x = load i32, ptr %p, align 8
br i1 %c, label %if, label %else
if:
- %y = load i32, i32* %p, align 16
+ %y = load i32, ptr %p, align 16
ret i32 %y
else:
ret i32 -1
}
-define void @caller_guaranteed_insufficient_aligned(i1 %c, i32* %p) {
+define void @caller_guaranteed_insufficient_aligned(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_insufficient_aligned
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_insufficient_aligned(i1 [[C]], i32* [[P]])
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_insufficient_aligned(i1 [[C]], ptr [[P]])
; CHECK-NEXT: ret void
;
- call i32 @callee_guaranteed_insufficient_aligned(i1 %c, i32* %p)
+ call i32 @callee_guaranteed_insufficient_aligned(i1 %c, ptr %p)
ret void
}
; This should not be promoted, as the caller only guarantees that the
; pointer is dereferenceable, not that it is aligned.
-define internal i32 @callee_not_guaranteed_aligned(i1 %c, i32* %p) {
+define internal i32 @callee_not_guaranteed_aligned(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_not_guaranteed_aligned
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P:%.*]]) {
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
-; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 16
+; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 16
; CHECK-NEXT: ret i32 [[X]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
br i1 %c, label %if, label %else
if:
- %x = load i32, i32* %p, align 16
+ %x = load i32, ptr %p, align 16
ret i32 %x
else:
ret i32 -1
}
-define void @caller_not_guaranteed_aligned(i1 %c, i32* dereferenceable(4) %p) {
+define void @caller_not_guaranteed_aligned(i1 %c, ptr dereferenceable(4) %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_not_guaranteed_aligned
-; CHECK-SAME: (i1 [[C:%.*]], i32* dereferenceable(4) [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_not_guaranteed_aligned(i1 [[C]], i32* [[P]])
+; CHECK-SAME: (i1 [[C:%.*]], ptr dereferenceable(4) [[P:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_not_guaranteed_aligned(i1 [[C]], ptr [[P]])
; CHECK-NEXT: ret void
;
- call i32 @callee_not_guaranteed_aligned(i1 %c, i32* %p)
+ call i32 @callee_not_guaranteed_aligned(i1 %c, ptr %p)
ret void
}
%struct.ss = type { i32, i64 }
-define internal void @f(%struct.ss* byval(%struct.ss) align 4 %b, i32* byval(i32) align 4 %X, i32 %i) nounwind {
+define internal void @f(ptr byval(%struct.ss) align 4 %b, ptr byval(i32) align 4 %X, i32 %i) nounwind {
; CHECK-LABEL: define {{[^@]+}}@f
; CHECK-SAME: (i32 [[B_0:%.*]], i32 [[X:%.*]], i32 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
- store i32 0, i32* %X
+ store i32 0, ptr %X
ret void
}
; Also make sure we don't drop the call zeroext attribute.
-define i32 @test(i32* %X) {
+define i32 @test(ptr %X) {
; CHECK-LABEL: define {{[^@]+}}@test
-; CHECK-SAME: (i32* [[X:%.*]]) {
+; CHECK-SAME: (ptr [[X:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8
-; CHECK-NEXT: [[TEMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
-; CHECK-NEXT: store i32 1, i32* [[TEMP1]], align 8
-; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
-; CHECK-NEXT: store i64 2, i64* [[TEMP4]], align 4
-; CHECK-NEXT: [[S_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, i32* [[S_0]], align 4
-; CHECK-NEXT: [[X_VAL:%.*]] = load i32, i32* [[X]], align 4
+; CHECK-NEXT: store i32 1, ptr [[S]], align 8
+; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1
+; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
+; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
; CHECK-NEXT: call void @f(i32 [[S_0_VAL]], i32 [[X_VAL]], i32 zeroext 0)
; CHECK-NEXT: ret i32 0
;
entry:
%S = alloca %struct.ss
- %temp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
- store i32 1, i32* %temp1, align 8
- %temp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
- store i64 2, i64* %temp4, align 4
+ store i32 1, ptr %S, align 8
+ %temp4 = getelementptr %struct.ss, ptr %S, i32 0, i32 1
+ store i64 2, ptr %temp4, align 4
- call void @f( %struct.ss* byval(%struct.ss) align 4 %S, i32* byval(i32) align 4 %X, i32 zeroext 0)
+ call void @f( ptr byval(%struct.ss) align 4 %S, ptr byval(i32) align 4 %X, i32 zeroext 0)
ret i32 0
}
; RUN: opt < %s -passes=argpromotion,mem2reg -S | FileCheck %s
target datalayout = "E-p:64:64:64-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"
-define internal i32 @test(i32* %X, i32* %Y) {
+define internal i32 @test(ptr %X, ptr %Y) {
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: (i32 [[X_0_VAL:%.*]], i32 [[Y_0_VAL:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_0_VAL]], [[Y_0_VAL]]
; CHECK-NEXT: ret i32 [[C]]
;
- %A = load i32, i32* %X
- %B = load i32, i32* %Y
+ %A = load i32, ptr %X
+ %B = load i32, ptr %Y
%C = add i32 %A, %B
ret i32 %C
}
-define internal i32 @caller(i32* %B) {
+define internal i32 @caller(ptr %B) {
; CHECK-LABEL: define {{[^@]+}}@caller
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32 1, i32 [[B_0_VAL]])
; CHECK-NEXT: ret i32 [[C]]
;
%A = alloca i32
- store i32 1, i32* %A
- %C = call i32 @test(i32* %A, i32* %B)
+ store i32 1, ptr %A
+ %C = call i32 @test(ptr %A, ptr %B)
ret i32 %C
}
; CHECK-NEXT: ret i32 [[X]]
;
%B = alloca i32
- store i32 2, i32* %B
- %X = call i32 @caller(i32* %B)
+ store i32 2, ptr %B
+ %X = call i32 @caller(ptr %B)
ret i32 %X
}
%opaque = type opaque
-define internal i32 @callee_basic(i8* %p) {
+define internal i32 @callee_basic(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_basic
; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) {
; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]]
; CHECK-NEXT: ret i32 [[Z]]
;
- %p.32 = bitcast i8* %p to i32*
- %x = load i32, i32* %p.32
- %p1 = getelementptr i8, i8* %p, i64 4
- %p1.32 = bitcast i8* %p1 to i32*
- %y = load i32, i32* %p1.32
+ %x = load i32, ptr %p
+ %p1 = getelementptr i8, ptr %p, i64 4
+ %y = load i32, ptr %p1
%z = add i32 %x, %y
ret i32 %z
}
-define void @caller_basic(i8* %p) {
+define void @caller_basic(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_basic
-; CHECK-SAME: (i8* [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[P]] to i32*
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[TMP1]], align 4
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* [[P]], i64 4
-; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
-; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, i32* [[TMP3]], align 4
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P]], i64 4
+; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @callee_basic(i32 [[P_VAL]], i32 [[P_VAL1]])
; CHECK-NEXT: ret void
;
- call i32 @callee_basic(i8* %p)
+ call i32 @callee_basic(ptr %p)
ret void
}
-define internal i32 @callee_opaque(%opaque* %p) {
+define internal i32 @callee_opaque(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_opaque
; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) {
; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]]
; CHECK-NEXT: ret i32 [[Z]]
;
- %p.32 = bitcast %opaque* %p to i32*
- %x = load i32, i32* %p.32
- %p1.32 = getelementptr i32, i32* %p.32, i64 1
- %y = load i32, i32* %p1.32
+ %x = load i32, ptr %p
+ %p1.32 = getelementptr i32, ptr %p, i64 1
+ %y = load i32, ptr %p1.32
%z = add i32 %x, %y
ret i32 %z
}
-define void @caller_opaque(%opaque* %p) {
+define void @caller_opaque(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_opaque
-; CHECK-SAME: (%opaque* [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast %opaque* [[P]] to i32*
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32, i32* [[TMP1]], align 4
-; CHECK-NEXT: [[TMP2:%.*]] = bitcast %opaque* [[P]] to i8*
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, i8* [[TMP2]], i64 4
-; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to i32*
-; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, i32* [[TMP4]], align 4
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[P]], i64 4
+; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP3]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @callee_opaque(i32 [[P_VAL]], i32 [[P_VAL1]])
; CHECK-NEXT: ret void
;
- call i32 @callee_opaque(%opaque* %p)
+ call i32 @callee_opaque(ptr %p)
ret void
}
%struct.ss = type { i32, i64 }
-define internal void @f(%struct.ss* byval(%struct.ss) align 8 %b, i32* byval(i32) align 4 %X) nounwind {
+define internal void @f(ptr byval(%struct.ss) align 8 %b, ptr byval(i32) align 4 %X) nounwind {
; CHECK-LABEL: define {{[^@]+}}@f
; CHECK-SAME: (i32 [[B_0:%.*]], i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
- store i32 0, i32* %X
+ store i32 0, ptr %X
ret void
}
-define i32 @test(i32* %X) {
+define i32 @test(ptr %X) {
; CHECK-LABEL: define {{[^@]+}}@test
-; CHECK-SAME: (i32* [[X:%.*]]) {
+; CHECK-SAME: (ptr [[X:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8
-; CHECK-NEXT: [[TEMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
-; CHECK-NEXT: store i32 1, i32* [[TEMP1]], align 8
-; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
-; CHECK-NEXT: store i64 2, i64* [[TEMP4]], align 4
-; CHECK-NEXT: [[S_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, i32* [[S_0]], align 4
-; CHECK-NEXT: [[X_VAL:%.*]] = load i32, i32* [[X]], align 4
+; CHECK-NEXT: store i32 1, ptr [[S]], align 8
+; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1
+; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
+; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
; CHECK-NEXT: call void @f(i32 [[S_0_VAL]], i32 [[X_VAL]])
; CHECK-NEXT: ret i32 0
;
entry:
%S = alloca %struct.ss, align 8
- %temp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
- store i32 1, i32* %temp1, align 8
- %temp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
- store i64 2, i64* %temp4, align 4
- call void @f( %struct.ss* byval(%struct.ss) align 8 %S, i32* byval(i32) align 4 %X)
+ store i32 1, ptr %S, align 8
+ %temp4 = getelementptr %struct.ss, ptr %S, i32 0, i32 1
+ store i64 2, ptr %temp4, align 4
+ call void @f( ptr byval(%struct.ss) align 8 %S, ptr byval(i32) align 4 %X)
ret i32 0
}
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -passes=argpromotion -S %s | FileCheck %s
%struct.A = type { float, [12 x i8], i64, [8 x i8] }
-define internal float @callee(%struct.A* byval(%struct.A) align 32 %0) {
+define internal float @callee(ptr byval(%struct.A) align 32 %0) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (float [[ARG_0:%.*]], i64 [[ARG_1:%.*]]) {
-; CHECK-NEXT: [[SUM:%.*]] = fadd float 0.000000e+00, [[ARG_0]]
-; CHECK-NEXT: [[COEFF:%.*]] = uitofp i64 [[ARG_1]] to float
-; CHECK-NEXT: [[RES:%.*]] = fmul float [[SUM]], [[COEFF]]
-; CHECK-NEXT: ret float [[RES]]
+; CHECK-SAME: (float [[DOT0_VAL:%.*]], i64 [[DOT16_VAL:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = fadd float 0.000000e+00, [[DOT0_VAL]]
+; CHECK-NEXT: [[TMP2:%.*]] = uitofp i64 [[DOT16_VAL]] to float
+; CHECK-NEXT: [[TMP3:%.*]] = fmul float [[TMP1]], [[TMP2]]
+; CHECK-NEXT: ret float [[TMP3]]
;
- %2 = getelementptr inbounds %struct.A, %struct.A* %0, i32 0, i32 0
- %3 = load float, float* %2, align 32
- %4 = fadd float 0.000000e+00, %3
- %5 = getelementptr inbounds %struct.A, %struct.A* %0, i32 0, i32 2
- %6 = load i64, i64* %5, align 16
- %7 = uitofp i64 %6 to float
- %8 = fmul float %4, %7
- ret float %8
+ %2 = load float, ptr %0, align 32
+ %3 = fadd float 0.000000e+00, %2
+ %4 = getelementptr inbounds %struct.A, ptr %0, i32 0, i32 2
+ %5 = load i64, ptr %4, align 16
+ %6 = uitofp i64 %5 to float
+ %7 = fmul float %3, %6
+ ret float %7
}
define float @caller(float %0) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (float [[ARG_0:%.*]]) {
-; CHECK-NEXT: [[TMP_0:%.*]] = alloca %struct.A, align 32
-; CHECK-NEXT: [[FL_PTR_0:%.*]] = getelementptr inbounds %struct.A, %struct.A* [[TMP_0]], i32 0, i32 0
-; CHECK-NEXT: store float [[ARG_0]], float* [[FL_PTR_0]], align 32
-; CHECK-NEXT: [[I64_PTR_0:%.*]] = getelementptr inbounds %struct.A, %struct.A* [[TMP_0]], i32 0, i32 2
-; CHECK-NEXT: store i64 2, i64* [[I64_PTR_0]], align 16
-; CHECK-NEXT: [[FL_PTR_1:%.*]] = getelementptr %struct.A, %struct.A* [[TMP_0]], i64 0, i32 0
-; CHECK-NEXT: [[FL_VAL:%.*]] = load float, float* [[FL_PTR_1]], align 32
-; CHECK-NEXT: [[I64_PTR_1:%.*]] = getelementptr %struct.A, %struct.A* [[TMP_0]], i64 0, i32 2
-; CHECK-NEXT: [[I64_VAL:%.*]] = load i64, i64* [[I64_PTR_1]], align 16
-; CHECK-NEXT: [[RES:%.*]] = call noundef float @callee(float [[FL_VAL]], i64 [[I64_VAL]])
-; CHECK-NEXT: ret float [[RES]]
+; CHECK-SAME: (float [[TMP0:%.*]]) {
+; CHECK-NEXT: [[TMP2:%.*]] = alloca [[STRUCT_A:%.*]], align 32
+; CHECK-NEXT: store float [[TMP0]], ptr [[TMP2]], align 32
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[TMP2]], i32 0, i32 2
+; CHECK-NEXT: store i64 2, ptr [[TMP3]], align 16
+; CHECK-NEXT: [[DOTVAL:%.*]] = load float, ptr [[TMP2]], align 32
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP2]], i64 16
+; CHECK-NEXT: [[DOTVAL1:%.*]] = load i64, ptr [[TMP4]], align 16
+; CHECK-NEXT: [[TMP5:%.*]] = call noundef float @callee(float [[DOTVAL]], i64 [[DOTVAL1]])
+; CHECK-NEXT: ret float [[TMP5]]
;
%2 = alloca %struct.A, align 32
- %3 = getelementptr inbounds %struct.A, %struct.A* %2, i32 0, i32 0
- store float %0, float* %3, align 32
- %4 = getelementptr inbounds %struct.A, %struct.A* %2, i32 0, i32 2
- store i64 2, i64* %4, align 16
- %5 = call noundef float @callee(%struct.A* byval(%struct.A) align 32 %2)
- ret float %5
+ store float %0, ptr %2, align 32
+ %3 = getelementptr inbounds %struct.A, ptr %2, i32 0, i32 2
+ store i64 2, ptr %3, align 16
+ %4 = call noundef float @callee(ptr byval(%struct.A) align 32 %2)
+ ret float %4
}
%struct.ss = type { i32, i64 }
-define internal void @f(%struct.ss* byval(%struct.ss) align 4 %b) nounwind {
+define internal void @f(ptr byval(%struct.ss) align 4 %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@f
-; CHECK-SAME: (i32 [[B_0:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
+; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
ret void
}
-define internal void @g(%struct.ss* byval(%struct.ss) align 32 %b) nounwind {
+define internal void @g(ptr byval(%struct.ss) align 32 %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@g
-; CHECK-SAME: (i32 [[B_0:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
+; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
ret void
}
;
; (If we ever change byval so a missing alignment isn't legal, we can
; just delete this test.)
-define internal void @h(%struct.ss* byval(%struct.ss) %b) nounwind {
+define internal void @h(ptr byval(%struct.ss) %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@h
-; CHECK-SAME: (%struct.ss* byval([[STRUCT_SS:%.*]]) [[B:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (ptr byval([[STRUCT_SS:%.*]]) [[B:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
-; CHECK-NEXT: [[TEMP1:%.*]] = load i32, i32* [[TEMP]], align 4
+; CHECK-NEXT: [[TEMP1:%.*]] = load i32, ptr [[B]], align 4
; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[TEMP1]], 1
-; CHECK-NEXT: store i32 [[TEMP2]], i32* [[TEMP]], align 4
+; CHECK-NEXT: store i32 [[TEMP2]], ptr [[B]], align 4
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
ret void
}
; Transform even if an argument is written to and then is loaded from.
-define internal void @k(%struct.ss* byval(%struct.ss) align 4 %b) nounwind {
+define internal void @k(ptr byval(%struct.ss) align 4 %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@k
-; CHECK-SAME: (i32 [[B_0:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
+; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
- %temp3 = load i32, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
+ %temp3 = load i32, ptr %b, align 4
ret void
}
; Transform even if a store instruction is the single user.
-define internal void @l(%struct.ss* byval(%struct.ss) align 4 %b) nounwind {
+define internal void @l(ptr byval(%struct.ss) align 4 %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@l
-; CHECK-SAME: (i32 [[B_0:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- store i32 1, i32* %temp, align 4
+ store i32 1, ptr %b, align 4
ret void
}
; Transform all the arguments creating the required number of 'alloca's and
; then optimize them out.
-define internal void @m(%struct.ss* byval(%struct.ss) align 4 %b, %struct.ss* byval(%struct.ss) align 4 %c) nounwind {
+define internal void @m(ptr byval(%struct.ss) align 4 %b, ptr byval(%struct.ss) align 4 %c) nounwind {
; CHECK-LABEL: define {{[^@]+}}@m
-; CHECK-SAME: (i32 [[B_0:%.*]], i32 [[C_0:%.*]], i64 [[C_1:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (i32 [[B_0_VAL:%.*]], i32 [[C_0_VAL:%.*]], i64 [[C_4_VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0]], 1
-; CHECK-NEXT: [[TEMP6:%.*]] = add i64 [[C_1]], 1
+; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
+; CHECK-NEXT: [[TEMP6:%.*]] = add i64 [[C_4_VAL]], 1
; CHECK-NEXT: ret void
;
entry:
- %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
- %temp1 = load i32, i32* %temp, align 4
+ %temp1 = load i32, ptr %b, align 4
%temp2 = add i32 %temp1, 1
- store i32 %temp2, i32* %temp, align 4
+ store i32 %temp2, ptr %b, align 4
- %temp3 = getelementptr %struct.ss, %struct.ss* %c, i32 0, i32 0
- store i32 %temp2, i32* %temp3, align 4
-
- %temp4 = getelementptr %struct.ss, %struct.ss* %c, i32 0, i32 1
- %temp5 = load i64, i64* %temp4, align 8
+ store i32 %temp2, ptr %c, align 4
+
+ %temp4 = getelementptr %struct.ss, ptr %c, i32 0, i32 1
+ %temp5 = load i64, ptr %temp4, align 8
%temp6 = add i64 %temp5, 1
- store i64 %temp6, i64* %temp4, align 8
+ store i64 %temp6, ptr %temp4, align 8
ret void
}
; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 32
-; CHECK-NEXT: [[TEMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
-; CHECK-NEXT: store i32 1, i32* [[TEMP1]], align 8
-; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
-; CHECK-NEXT: store i64 2, i64* [[TEMP4]], align 4
-; CHECK-NEXT: [[S_0_0_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_0_0_0_VAL:%.*]] = load i32, i32* [[S_0_0_0]], align 4
-; CHECK-NEXT: call void @f(i32 [[S_0_0_0_VAL]])
-; CHECK-NEXT: [[S_1_0_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_1_0_0_VAL:%.*]] = load i32, i32* [[S_1_0_0]], align 4
-; CHECK-NEXT: call void @g(i32 [[S_1_0_0_VAL]])
-; CHECK-NEXT: call void @h(%struct.ss* byval([[STRUCT_SS]]) [[S]])
-; CHECK-NEXT: [[S_2_0_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_2_0_0_VAL:%.*]] = load i32, i32* [[S_2_0_0]], align 4
-; CHECK-NEXT: call void @k(i32 [[S_2_0_0_VAL]])
-; CHECK-NEXT: [[S_3_0_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_3_0_0_VAL:%.*]] = load i32, i32* [[S_3_0_0]], align 4
-; CHECK-NEXT: call void @l(i32 [[S_3_0_0_VAL]])
-; CHECK-NEXT: [[S_4_0_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_4_0_0_VAL:%.*]] = load i32, i32* [[S_4_0_0]], align 4
-; CHECK-NEXT: [[S_4_1_0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 0
-; CHECK-NEXT: [[S_4_1_0_VAL:%.*]] = load i32, i32* [[S_4_1_0]], align 4
-; CHECK-NEXT: [[S_4_1_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i64 0, i32 1
-; CHECK-NEXT: [[S_4_1_1_VAL:%.*]] = load i64, i64* [[S_4_1_1]], align 8
-; CHECK-NEXT: call void @m(i32 [[S_4_0_0_VAL]], i32 [[S_4_1_0_VAL]], i64 [[S_4_1_1_VAL]])
+; CHECK-NEXT: store i32 1, ptr [[S]], align 8
+; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1
+; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
+; CHECK-NEXT: [[S_VAL:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: call void @f(i32 [[S_VAL]])
+; CHECK-NEXT: [[S_VAL1:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: call void @g(i32 [[S_VAL1]])
+; CHECK-NEXT: call void @h(ptr byval([[STRUCT_SS]]) [[S]])
+; CHECK-NEXT: [[S_VAL2:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: call void @k(i32 [[S_VAL2]])
+; CHECK-NEXT: [[S_VAL3:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: call void @l(i32 [[S_VAL3]])
+; CHECK-NEXT: [[S_VAL4:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: [[S_VAL5:%.*]] = load i32, ptr [[S]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i64 4
+; CHECK-NEXT: [[S_VAL6:%.*]] = load i64, ptr [[TMP0]], align 8
+; CHECK-NEXT: call void @m(i32 [[S_VAL4]], i32 [[S_VAL5]], i64 [[S_VAL6]])
; CHECK-NEXT: ret i32 0
;
entry:
%S = alloca %struct.ss, align 32
- %temp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
- store i32 1, i32* %temp1, align 8
- %temp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
- store i64 2, i64* %temp4, align 4
- call void @f(%struct.ss* byval(%struct.ss) align 4 %S) nounwind
- call void @g(%struct.ss* byval(%struct.ss) align 32 %S) nounwind
- call void @h(%struct.ss* byval(%struct.ss) %S) nounwind
- call void @k(%struct.ss* byval(%struct.ss) align 4 %S) nounwind
- call void @l(%struct.ss* byval(%struct.ss) align 4 %S) nounwind
- call void @m(%struct.ss* byval(%struct.ss) align 4 %S, %struct.ss* byval(%struct.ss) align 4 %S) nounwind
+ store i32 1, ptr %S, align 8
+ %temp4 = getelementptr %struct.ss, ptr %S, i32 0, i32 1
+ store i64 2, ptr %temp4, align 4
+ call void @f(ptr byval(%struct.ss) align 4 %S) nounwind
+ call void @g(ptr byval(%struct.ss) align 32 %S) nounwind
+ call void @h(ptr byval(%struct.ss) %S) nounwind
+ call void @k(ptr byval(%struct.ss) align 4 %S) nounwind
+ call void @l(ptr byval(%struct.ss) align 4 %S) nounwind
+ call void @m(ptr byval(%struct.ss) align 4 %S, ptr byval(%struct.ss) align 4 %S) nounwind
ret i32 0
}
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
@G1 = constant i32 0
-@G2 = constant i32* @G1
+@G2 = constant ptr @G1
-define internal i32 @test(i32** %x) {
+define internal i32 @test(ptr %x) {
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: (i32 [[X_0_VAL_0_VAL:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[X_0_VAL_0_VAL]]
;
entry:
- %y = load i32*, i32** %x
- %z = load i32, i32* %y
+ %y = load ptr, ptr %x
+ %z = load i32, ptr %y
ret i32 %z
}
define i32 @caller() {
; CHECK-LABEL: define {{[^@]+}}@caller() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[G2_VAL:%.*]] = load i32*, i32** @G2, align 8
-; CHECK-NEXT: [[G2_VAL_VAL:%.*]] = load i32, i32* [[G2_VAL]], align 4
+; CHECK-NEXT: [[G2_VAL:%.*]] = load ptr, ptr @G2, align 8
+; CHECK-NEXT: [[G2_VAL_VAL:%.*]] = load i32, ptr [[G2_VAL]], align 4
; CHECK-NEXT: [[X:%.*]] = call i32 @test(i32 [[G2_VAL_VAL]])
; CHECK-NEXT: ret i32 [[X]]
;
entry:
- %x = call i32 @test(i32** @G2)
+ %x = call i32 @test(ptr @G2)
ret i32 %x
}
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
; Don't promote around control flow.
-define internal i32 @callee(i1 %C, i32* %P) {
+define internal i32 @callee(i1 %C, ptr %P) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P:%.*]]) {
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CHECK: T:
; CHECK-NEXT: ret i32 17
; CHECK: F:
-; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
+; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4
; CHECK-NEXT: ret i32 [[X]]
;
entry:
ret i32 17
F:
- %X = load i32, i32* %P
+ %X = load i32, ptr %P
ret i32 %X
}
define i32 @foo() {
; CHECK-LABEL: define {{[^@]+}}@foo() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 true, i32* null)
+; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 true, ptr null)
; CHECK-NEXT: ret i32 [[X]]
;
entry:
- %X = call i32 @callee(i1 true, i32* null)
+ %X = call i32 @callee(i1 true, ptr null)
ret i32 %X
}
target datalayout = "E-p:64:64:64-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"
-define internal i32 @callee(i1 %C, i32* %P) {
+define internal i32 @callee(i1 %C, ptr %P) {
; CHECK-LABEL: define {{[^@]+}}@callee
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
ret i32 17
F: ; preds = %0
- %X = load i32, i32* %P ; <i32> [#uses=1]
+ %X = load i32, ptr %P ; <i32> [#uses=1]
ret i32 %X
}
define i32 @foo() {
; CHECK-LABEL: define {{[^@]+}}@foo() {
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 17, i32* [[A]], align 4
-; CHECK-NEXT: [[A_VAL:%.*]] = load i32, i32* [[A]], align 4
+; CHECK-NEXT: store i32 17, ptr [[A]], align 4
+; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]], align 4
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[A_VAL]])
; CHECK-NEXT: ret i32 [[X]]
;
- %A = alloca i32 ; <i32*> [#uses=2]
- store i32 17, i32* %A
- %X = call i32 @callee( i1 false, i32* %A ) ; <i32> [#uses=1]
+ %A = alloca i32 ; <ptr> [#uses=2]
+ store i32 17, ptr %A
+ %X = call i32 @callee( i1 false, ptr %A ) ; <i32> [#uses=1]
ret i32 %X
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -S < %s -passes=inline,argpromotion | FileCheck %s --check-prefix=ARGPROMOTION
-%S = type { %S* }
+%S = type { ptr }
; Inlining should nuke the invoke (and any inlined calls) here even with
; argument promotion running along with it.
-define void @zot() personality i32 (...)* @wibble {
-; ARGPROMOTION-LABEL: define {{[^@]+}}@zot() personality i32 (...)* @wibble {
+define void @zot() personality ptr @wibble {
+; ARGPROMOTION-LABEL: define {{[^@]+}}@zot() personality ptr @wibble {
; ARGPROMOTION-NEXT: bb:
; ARGPROMOTION-NEXT: unreachable
; ARGPROMOTION: hoge.exit:
; ARGPROMOTION: bb1:
; ARGPROMOTION-NEXT: unreachable
; ARGPROMOTION: bb2:
-; ARGPROMOTION-NEXT: [[TEMP:%.*]] = landingpad { i8*, i32 }
+; ARGPROMOTION-NEXT: [[TEMP:%.*]] = landingpad { ptr, i32 }
; ARGPROMOTION-NEXT: cleanup
; ARGPROMOTION-NEXT: unreachable
;
unreachable
bb2:
- %temp = landingpad { i8*, i32 }
+ %temp = landingpad { ptr, i32 }
cleanup
unreachable
}
define internal void @hoge() {
bb:
- %temp = call fastcc i8* @spam(i1 (i8*)* @eggs)
- %temp1 = call fastcc i8* @spam(i1 (i8*)* @barney)
+ %temp = call fastcc ptr @spam(ptr @eggs)
+ %temp1 = call fastcc ptr @spam(ptr @barney)
unreachable
}
-define internal fastcc i8* @spam(i1 (i8*)* %arg) {
+define internal fastcc ptr @spam(ptr %arg) {
bb:
unreachable
}
-define internal i1 @eggs(i8* %arg) {
+define internal i1 @eggs(ptr %arg) {
; ARGPROMOTION-LABEL: define {{[^@]+}}@eggs() {
; ARGPROMOTION-NEXT: bb:
; ARGPROMOTION-NEXT: unreachable
;
bb:
- %temp = call zeroext i1 @barney(i8* %arg)
+ %temp = call zeroext i1 @barney(ptr %arg)
unreachable
}
-define internal i1 @barney(i8* %arg) {
+define internal i1 @barney(ptr %arg) {
bb:
ret i1 undef
}
; ARGPROMOTION-NEXT: bb:
; ARGPROMOTION-NEXT: [[TEMP:%.*]] = alloca [[S:%.*]], align 8
; ARGPROMOTION-NEXT: [[TEMP1:%.*]] = alloca [[S]], align 8
-; ARGPROMOTION-NEXT: [[TEMP2:%.*]] = call i32 @test_inf_promote_callee(%S* [[TEMP]], %S* [[TEMP1]])
+; ARGPROMOTION-NEXT: [[TEMP2:%.*]] = call i32 @test_inf_promote_callee(ptr [[TEMP]], ptr [[TEMP1]])
; ARGPROMOTION-NEXT: ret i32 0
;
bb:
%temp = alloca %S
%temp1 = alloca %S
- %temp2 = call i32 @test_inf_promote_callee(%S* %temp, %S* %temp1)
+ %temp2 = call i32 @test_inf_promote_callee(ptr %temp, ptr %temp1)
ret i32 0
}
-define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) {
+define internal i32 @test_inf_promote_callee(ptr %arg, ptr %arg1) {
; ARGPROMOTION-LABEL: define {{[^@]+}}@test_inf_promote_callee
-; ARGPROMOTION-SAME: (%S* [[ARG:%.*]], %S* [[ARG1:%.*]]) {
+; ARGPROMOTION-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]]) {
; ARGPROMOTION-NEXT: bb:
-; ARGPROMOTION-NEXT: [[TEMP:%.*]] = getelementptr [[S:%.*]], %S* [[ARG1]], i32 0, i32 0
-; ARGPROMOTION-NEXT: [[TEMP2:%.*]] = load %S*, %S** [[TEMP]], align 8
-; ARGPROMOTION-NEXT: [[TEMP3:%.*]] = getelementptr [[S]], %S* [[ARG]], i32 0, i32 0
-; ARGPROMOTION-NEXT: [[TEMP4:%.*]] = load %S*, %S** [[TEMP3]], align 8
-; ARGPROMOTION-NEXT: [[TEMP5:%.*]] = call i32 @test_inf_promote_callee(%S* [[TEMP4]], %S* [[TEMP2]])
+; ARGPROMOTION-NEXT: [[TEMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
+; ARGPROMOTION-NEXT: [[TEMP4:%.*]] = load ptr, ptr [[ARG]], align 8
+; ARGPROMOTION-NEXT: [[TEMP5:%.*]] = call i32 @test_inf_promote_callee(ptr [[TEMP4]], ptr [[TEMP2]])
; ARGPROMOTION-NEXT: ret i32 0
;
bb:
- %temp = getelementptr %S, %S* %arg1, i32 0, i32 0
- %temp2 = load %S*, %S** %temp
- %temp3 = getelementptr %S, %S* %arg, i32 0, i32 0
- %temp4 = load %S*, %S** %temp3
- %temp5 = call i32 @test_inf_promote_callee(%S* %temp4, %S* %temp2)
+ %temp2 = load ptr, ptr %arg1
+ %temp4 = load ptr, ptr %arg
+ %temp5 = call i32 @test_inf_promote_callee(ptr %temp4, ptr %temp2)
ret i32 0
}
declare void @sink(i32)
-define internal void @test(i32** %X) !dbg !2 {
+define internal void @test(ptr %X) !dbg !2 {
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: (i32 [[X_0_VAL_0_VAL:%.*]]) !dbg [[DBG3:![0-9]+]] {
; CHECK-NEXT: call void @sink(i32 [[X_0_VAL_0_VAL]])
; CHECK-NEXT: ret void
;
- %1 = load i32*, i32** %X, align 8
- %2 = load i32, i32* %1, align 8
+ %1 = load ptr, ptr %X, align 8
+ %2 = load i32, ptr %1, align 8
call void @sink(i32 %2)
ret void
}
; Do not promote because there is a store of the pointer %P itself. Even if %P
; had been promoted as a byval argument, the result would have been not
; optimizable for SROA.
-define internal void @test_byval(%struct.pair* byval(%struct.pair) align 4 %P) {
+define internal void @test_byval(ptr byval(%struct.pair) align 4 %P) {
; CHECK-LABEL: define {{[^@]+}}@test_byval
-; CHECK-SAME: ([[STRUCT_PAIR:%.*]]* byval([[STRUCT_PAIR]]) align 4 [[P:%.*]]) {
-; CHECK-NEXT: [[SINK:%.*]] = alloca i32*, align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr [[STRUCT_PAIR]], [[STRUCT_PAIR]]* [[P]], i32 0, i32 0
-; CHECK-NEXT: store i32* [[TEMP]], i32** [[SINK]], align 8
+; CHECK-SAME: (ptr byval([[STRUCT_PAIR:%.*]]) align 4 [[P:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: store ptr [[P]], ptr [[TMP1]], align 8
; CHECK-NEXT: ret void
;
- %1 = alloca i32*, align 8
- %2 = getelementptr %struct.pair, %struct.pair* %P, i32 0, i32 0
- store i32* %2, i32** %1, align 8 ; to protect from promotion
+ %1 = alloca ptr, align 8
+ store ptr %P, ptr %1, align 8 ; to protect from promotion
ret void
}
-define void @caller(i32** %Y, %struct.pair* %P) {
+define void @caller(ptr %Y, ptr %P) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i32** [[Y:%.*]], %struct.pair* [[P:%.*]]) {
-; CHECK-NEXT: [[Y_VAL:%.*]] = load i32*, i32** [[Y]], align 8, !dbg [[DBG4:![0-9]+]]
-; CHECK-NEXT: [[Y_VAL_VAL:%.*]] = load i32, i32* [[Y_VAL]], align 8, !dbg [[DBG4]]
+; CHECK-SAME: (ptr [[Y:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8, !dbg [[DBG4:![0-9]+]]
+; CHECK-NEXT: [[Y_VAL_VAL:%.*]] = load i32, ptr [[Y_VAL]], align 8, !dbg [[DBG4]]
; CHECK-NEXT: call void @test(i32 [[Y_VAL_VAL]]), !dbg [[DBG4]]
-; CHECK-NEXT: call void @test_byval([[STRUCT_PAIR]]* byval([[STRUCT_PAIR]]) align 4 [[P]]), !dbg [[DBG5:![0-9]+]]
+; CHECK-NEXT: call void @test_byval(ptr byval([[STRUCT_PAIR:%.*]]) align 4 [[P]]), !dbg [[DBG5:![0-9]+]]
; CHECK-NEXT: ret void
;
- call void @test(i32** %Y), !dbg !1
+ call void @test(ptr %Y), !dbg !1
- call void @test_byval(%struct.pair* byval(%struct.pair) align 4 %P), !dbg !6
+ call void @test_byval(ptr byval(%struct.pair) align 4 %P), !dbg !6
ret void
}
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
; RUN: opt -passes=argpromotion -S %s | FileCheck %s
-@glob = external global i32*
+@glob = external global ptr
; No arguments in @callee can be promoted, but it contains a dead GEP. Make
; sure it is not removed, as we do not perform any promotion.
-define i32 @caller(i32* %ptr) {
+define i32 @caller(ptr %ptr) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i32* [[PTR:%.*]]) {
-; CHECK-NEXT: call void @callee(i32* [[PTR]], i32* [[PTR]], i32* [[PTR]])
+; CHECK-SAME: (ptr [[PTR:%.*]]) {
+; CHECK-NEXT: call void @callee(ptr [[PTR]], ptr [[PTR]], ptr [[PTR]])
; CHECK-NEXT: ret i32 0
;
- call void @callee(i32* %ptr, i32* %ptr, i32* %ptr)
+ call void @callee(ptr %ptr, ptr %ptr, ptr %ptr)
ret i32 0
}
-define internal void @callee(i32* %arg, i32* %arg1, i32* %arg2) {
+define internal void @callee(ptr %arg, ptr %arg1, ptr %arg2) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32* [[ARG:%.*]], i32* [[ARG1:%.*]], i32* [[ARG2:%.*]]) {
-; CHECK-NEXT: call void @external_fn(i32* [[ARG]], i32* [[ARG1]])
-; CHECK-NEXT: [[DEAD_GEP:%.*]] = getelementptr inbounds i32, i32* [[ARG1]], i32 17
-; CHECK-NEXT: store i32* [[ARG2]], i32** @glob, align 8
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) {
+; CHECK-NEXT: call void @external_fn(ptr [[ARG]], ptr [[ARG1]])
+; CHECK-NEXT: [[DEAD_GEP:%.*]] = getelementptr inbounds i32, ptr [[ARG1]], i32 17
+; CHECK-NEXT: store ptr [[ARG2]], ptr @glob, align 8
; CHECK-NEXT: ret void
;
- call void @external_fn(i32* %arg, i32* %arg1)
- %dead.gep = getelementptr inbounds i32, i32* %arg1, i32 17
- store i32* %arg2, i32** @glob, align 8
+ call void @external_fn(ptr %arg, ptr %arg1)
+ %dead.gep = getelementptr inbounds i32, ptr %arg1, i32 17
+ store ptr %arg2, ptr @glob, align 8
ret void
}
-declare void @external_fn(i32*, i32*)
+declare void @external_fn(ptr, ptr)
define void @run() {
; CHECK-LABEL: define {{[^@]+}}@run() {
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast %union.u* bitcast (%struct.s* @b to %union.u*) to i8*
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[TMP0]], i64 10
-; CHECK-NEXT: [[DOTVAL:%.*]] = load i8, i8* [[TMP1]], align 1
-; CHECK-NEXT: [[TMP2:%.*]] = tail call i8 @UseLongDoubleUnsafely(i8 [[DOTVAL]])
-; CHECK-NEXT: [[DOT0:%.*]] = getelementptr [[UNION_U:%.*]], %union.u* bitcast (%struct.s* @b to %union.u*), i64 0, i32 0
-; CHECK-NEXT: [[DOT0_VAL:%.*]] = load x86_fp80, x86_fp80* [[DOT0]], align 16
-; CHECK-NEXT: [[TMP3:%.*]] = tail call x86_fp80 @UseLongDoubleSafely(x86_fp80 [[DOT0_VAL]])
-; CHECK-NEXT: [[TMP4:%.*]] = tail call x86_fp80 @UseLongDoubleSafelyNoPromotion(%union.u* byval(%union.u) align 16 bitcast (%struct.s* @b to %union.u*))
-; CHECK-NEXT: [[TMP5:%.*]] = bitcast %struct.Foo* @a to i64*
-; CHECK-NEXT: [[A_VAL:%.*]] = load i64, i64* [[TMP5]], align 8
-; CHECK-NEXT: [[TMP6:%.*]] = call i64 @AccessPaddingOfStruct(i64 [[A_VAL]])
-; CHECK-NEXT: [[TMP7:%.*]] = call i64 @CaptureAStruct(%struct.Foo* byval([[STRUCT_FOO:%.*]]) @a)
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr @b, i64 10
+; CHECK-NEXT: [[B_VAL:%.*]] = load i8, ptr [[TMP1]], align 1
+; CHECK-NEXT: [[TMP2:%.*]] = tail call i8 @UseLongDoubleUnsafely(i8 [[B_VAL]])
+; CHECK-NEXT: [[B_VAL1:%.*]] = load x86_fp80, ptr @b, align 16
+; CHECK-NEXT: [[TMP3:%.*]] = tail call x86_fp80 @UseLongDoubleSafely(x86_fp80 [[B_VAL1]])
+; CHECK-NEXT: [[TMP4:%.*]] = tail call x86_fp80 @UseLongDoubleSafelyNoPromotion(ptr byval([[UNION_U:%.*]]) align 16 @b)
+; CHECK-NEXT: [[A_VAL:%.*]] = load i64, ptr @a, align 8
+; CHECK-NEXT: [[TMP5:%.*]] = call i64 @AccessPaddingOfStruct(i64 [[A_VAL]])
+; CHECK-NEXT: [[TMP6:%.*]] = call i64 @CaptureAStruct(ptr byval([[STRUCT_FOO:%.*]]) @a)
; CHECK-NEXT: ret void
;
- tail call i8 @UseLongDoubleUnsafely(%union.u* byval(%union.u) align 16 bitcast (%struct.s* @b to %union.u*))
- tail call x86_fp80 @UseLongDoubleSafely(%union.u* byval(%union.u) align 16 bitcast (%struct.s* @b to %union.u*))
- tail call x86_fp80 @UseLongDoubleSafelyNoPromotion(%union.u* byval(%union.u) align 16 bitcast (%struct.s* @b to %union.u*))
- call i64 @AccessPaddingOfStruct(%struct.Foo* byval(%struct.Foo) @a)
- call i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) @a)
+ tail call i8 @UseLongDoubleUnsafely(ptr byval(%union.u) align 16 @b)
+ tail call x86_fp80 @UseLongDoubleSafely(ptr byval(%union.u) align 16 @b)
+ tail call x86_fp80 @UseLongDoubleSafelyNoPromotion(ptr byval(%union.u) align 16 @b)
+ call i64 @AccessPaddingOfStruct(ptr byval(%struct.Foo) @a)
+ call i64 @CaptureAStruct(ptr byval(%struct.Foo) @a)
ret void
}
-define internal i8 @UseLongDoubleUnsafely(%union.u* byval(%union.u) align 16 %arg) {
+define internal i8 @UseLongDoubleUnsafely(ptr byval(%union.u) align 16 %arg) {
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely
-; CHECK-SAME: (i8 [[ARG_0_VAL:%.*]]) {
-; CHECK-NEXT: ret i8 [[ARG_0_VAL]]
+; CHECK-SAME: (i8 [[ARG_10_VAL:%.*]]) {
+; CHECK-NEXT: ret i8 [[ARG_10_VAL]]
;
- %bitcast = bitcast %union.u* %arg to %struct.s*
- %gep = getelementptr inbounds %struct.s, %struct.s* %bitcast, i64 0, i32 2
- %result = load i8, i8* %gep
+ %gep = getelementptr inbounds %struct.s, ptr %arg, i64 0, i32 2
+ %result = load i8, ptr %gep
ret i8 %result
}
-define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval(%union.u) align 16 %arg) {
+define internal x86_fp80 @UseLongDoubleSafely(ptr byval(%union.u) align 16 %arg) {
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleSafely
; CHECK-SAME: (x86_fp80 [[ARG_0_VAL:%.*]]) {
; CHECK-NEXT: ret x86_fp80 [[ARG_0_VAL]]
;
- %gep = getelementptr inbounds %union.u, %union.u* %arg, i64 0, i32 0
- %fp80 = load x86_fp80, x86_fp80* %gep
+ %fp80 = load x86_fp80, ptr %arg
ret x86_fp80 %fp80
}
-define internal x86_fp80 @UseLongDoubleSafelyNoPromotion(%union.u* byval(%union.u) align 16 %arg) {
+define internal x86_fp80 @UseLongDoubleSafelyNoPromotion(ptr byval(%union.u) align 16 %arg) {
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleSafelyNoPromotion
-; CHECK-SAME: ([[UNION_U]]* byval([[UNION_U]]) align 16 [[ARG:%.*]]) {
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[UNION_U]], [[UNION_U]]* [[ARG]], i64 0, i32 0
-; CHECK-NEXT: [[TMP_IDX:%.*]] = alloca i64, align 8
-; CHECK-NEXT: store i64 0, i64* [[TMP_IDX]], align 8
-; CHECK-NEXT: [[IDX:%.*]] = load i64, i64* [[TMP_IDX]], align 8
-; CHECK-NEXT: [[GEP_IDX:%.*]] = getelementptr inbounds [[UNION_U]], [[UNION_U]]* [[ARG]], i64 [[IDX]], i32 0
-; CHECK-NEXT: [[FP80:%.*]] = load x86_fp80, x86_fp80* [[GEP]]
+; CHECK-SAME: (ptr byval([[UNION_U:%.*]]) align 16 [[ARG:%.*]]) {
+; CHECK-NEXT: [[IDX_SLOT:%.*]] = alloca i64, align 8
+; CHECK-NEXT: store i64 0, ptr [[IDX_SLOT]], align 8
+; CHECK-NEXT: [[IDX:%.*]] = load i64, ptr [[IDX_SLOT]], align 8
+; CHECK-NEXT: [[GEP_IDX:%.*]] = getelementptr inbounds [[UNION_U]], ptr [[ARG]], i64 [[IDX]], i32 0
+; CHECK-NEXT: [[FP80:%.*]] = load x86_fp80, ptr [[ARG]], align 16
; CHECK-NEXT: ret x86_fp80 [[FP80]]
;
- %gep = getelementptr inbounds %union.u, %union.u* %arg, i64 0, i32 0
%idx_slot = alloca i64, align 8
- store i64 0, i64* %idx_slot, align 8
- %idx = load i64, i64* %idx_slot, align 8
- %gep_idx = getelementptr inbounds %union.u, %union.u* %arg, i64 %idx, i32 0 ; to protect from promotion
- %fp80 = load x86_fp80, x86_fp80* %gep
+ store i64 0, ptr %idx_slot, align 8
+ %idx = load i64, ptr %idx_slot, align 8
+ %gep_idx = getelementptr inbounds %union.u, ptr %arg, i64 %idx, i32 0 ; to protect from promotion
+ %fp80 = load x86_fp80, ptr %arg
ret x86_fp80 %fp80
}
-define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval(%struct.Foo) %a) {
+define internal i64 @AccessPaddingOfStruct(ptr byval(%struct.Foo) %a) {
; CHECK-LABEL: define {{[^@]+}}@AccessPaddingOfStruct
; CHECK-SAME: (i64 [[A_0_VAL:%.*]]) {
; CHECK-NEXT: ret i64 [[A_0_VAL]]
;
- %p = bitcast %struct.Foo* %a to i64*
- %v = load i64, i64* %p
+ %v = load i64, ptr %a
ret i64 %v
}
-define internal i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) %a) {
+define internal i64 @CaptureAStruct(ptr byval(%struct.Foo) %a) {
; CHECK-LABEL: define {{[^@]+}}@CaptureAStruct
-; CHECK-SAME: (%struct.Foo* byval([[STRUCT_FOO:%.*]]) [[A:%.*]]) {
+; CHECK-SAME: (ptr byval([[STRUCT_FOO:%.*]]) [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
+; CHECK-NEXT: [[A_PTR:%.*]] = alloca ptr, align 8
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
-; CHECK-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
-; CHECK-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A]], i64 0
+; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ null, [[ENTRY:%.*]] ], [ [[A]], [[LOOP]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = phi ptr [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
+; CHECK-NEXT: store ptr [[PHI]], ptr [[A_PTR]], align 8
; CHECK-NEXT: br label [[LOOP]]
;
entry:
- %a_ptr = alloca %struct.Foo*
+ %a_ptr = alloca ptr
br label %loop
loop:
- %phi = phi %struct.Foo* [ null, %entry ], [ %gep, %loop ]
- %0 = phi %struct.Foo* [ %a, %entry ], [ %0, %loop ]
- store %struct.Foo* %phi, %struct.Foo** %a_ptr
- %gep = getelementptr %struct.Foo, %struct.Foo* %a, i64 0
+ %phi = phi ptr [ null, %entry ], [ %a, %loop ]
+ %0 = phi ptr [ %a, %entry ], [ %0, %loop ]
+ store ptr %phi, ptr %a_ptr
br label %loop
}
%struct.ss = type { i32, i32 }
; Argpromote + sroa should change this to passing the two integers by value.
-define internal i32 @f(%struct.ss* inalloca(%struct.ss) %s) {
+define internal i32 @f(ptr inalloca(%struct.ss) %s) {
; CHECK-LABEL: define {{[^@]+}}@f
; CHECK-SAME: (i32 [[S_0_VAL:%.*]], i32 [[S_4_VAL:%.*]]) unnamed_addr {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[R]]
;
entry:
- %f0 = getelementptr %struct.ss, %struct.ss* %s, i32 0, i32 0
- %f1 = getelementptr %struct.ss, %struct.ss* %s, i32 0, i32 1
- %a = load i32, i32* %f0, align 4
- %b = load i32, i32* %f1, align 4
+ %f1 = getelementptr %struct.ss, ptr %s, i32 0, i32 1
+ %a = load i32, ptr %s, align 4
+ %b = load i32, ptr %f1, align 4
%r = add i32 %a, %b
ret i32 %r
}
;
entry:
%S = alloca inalloca %struct.ss
- %f0 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
- %f1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
- store i32 1, i32* %f0, align 4
- store i32 2, i32* %f1, align 4
- %r = call i32 @f(%struct.ss* inalloca(%struct.ss) %S)
+ %f1 = getelementptr %struct.ss, ptr %S, i32 0, i32 1
+ store i32 1, ptr %S, align 4
+ store i32 2, ptr %f1, align 4
+ %r = call i32 @f(ptr inalloca(%struct.ss) %S)
ret i32 %r
}
; Argpromote can't promote %a because of the icmp use.
-define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca(%struct.ss) %b) nounwind {
+define internal i1 @g(ptr %a, ptr inalloca(%struct.ss) %b) nounwind {
; CHECK-LABEL: define {{[^@]+}}@g
-; CHECK-SAME: (%struct.ss* [[A:%.*]], %struct.ss* [[B:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C:%.*]] = icmp eq %struct.ss* [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
entry:
- %c = icmp eq %struct.ss* %a, %b
+ %c = icmp eq ptr %a, %b
ret i1 %c
}
; CHECK-LABEL: define {{[^@]+}}@test() local_unnamed_addr {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4
-; CHECK-NEXT: [[C:%.*]] = call fastcc i1 @g(%struct.ss* [[S]], %struct.ss* [[S]])
+; CHECK-NEXT: [[C:%.*]] = call fastcc i1 @g(ptr [[S]], ptr [[S]])
; CHECK-NEXT: ret i32 0
;
entry:
%S = alloca inalloca %struct.ss
- %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca(%struct.ss) %S)
+ %c = call i1 @g(ptr %S, ptr inalloca(%struct.ss) %S)
ret i32 0
}
@G = constant i32 0
-define internal i32 @a(i32* %x) {
+define internal i32 @a(ptr %x) {
; CHECK-LABEL: define {{[^@]+}}@a
; CHECK-SAME: (i32 [[X_0_VAL:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 [[X_0_VAL]]
;
entry:
- %v = load i32, i32* %x
+ %v = load i32, ptr %x
ret i32 %v
}
define i32 @b() {
; CHECK-LABEL: define {{[^@]+}}@b() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* @G, align 4
+; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @G, align 4
; CHECK-NEXT: [[V:%.*]] = call i32 @a(i32 [[G_VAL]])
; CHECK-NEXT: ret i32 [[V]]
;
entry:
- %v = call i32 @a(i32* @G)
+ %v = call i32 @a(ptr @G)
ret i32 %v
}
define i32 @c() {
; CHECK-LABEL: define {{[^@]+}}@c() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* @G, align 4
+; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @G, align 4
; CHECK-NEXT: [[V1:%.*]] = call i32 @a(i32 [[G_VAL]])
; CHECK-NEXT: [[V2:%.*]] = call i32 @b()
; CHECK-NEXT: [[RESULT:%.*]] = add i32 [[V1]], [[V2]]
; CHECK-NEXT: ret i32 [[RESULT]]
;
entry:
- %v1 = call i32 @a(i32* @G)
+ %v1 = call i32 @a(ptr @G)
%v2 = call i32 @b()
%result = add i32 %v1, %v2
ret i32 %result
; The argument cannot be promoted, as we do not know whether the load can be
; speculatively executed.
-define internal i32 @callee(i32* %p) {
+define internal i32 @callee(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32* [[P:%.*]]) {
+; CHECK-SAME: (ptr [[P:%.*]]) {
; CHECK-NEXT: call void @may_not_return()
-; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
+; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4
; CHECK-NEXT: ret i32 [[X]]
;
call void @may_not_return() readnone
- %x = load i32, i32* %p
+ %x = load i32, ptr %p
ret i32 %x
}
-define void @caller(i32* %p) {
+define void @caller(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i32* [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee(i32* [[P]])
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee(ptr [[P]])
; CHECK-NEXT: ret void
;
- call i32 @callee(i32* %p)
+ call i32 @callee(ptr %p)
ret void
}
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -passes=argpromotion -S %s | FileCheck %s
-define internal i32 @callee2(i32* noundef %0) {
+define internal i32 @callee2(ptr noundef %0) {
; CHECK-LABEL: define {{[^@]+}}@callee2
-; CHECK-SAME: (i32 [[P_0:%.*]], i32 [[P_1:%.*]]) {
-; CHECK-NEXT: [[SUM:%.*]] = add nsw i32 [[P_0]], [[P_1]]
-; CHECK-NEXT: ret i32 [[SUM]]
+; CHECK-SAME: (i32 [[DOT0_VAL:%.*]], i32 [[DOT4_VAL:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[DOT0_VAL]], [[DOT4_VAL]]
+; CHECK-NEXT: ret i32 [[TMP1]]
;
- %2 = getelementptr inbounds i32, i32* %0, i64 0
- %3 = load i32, i32* %2, align 4
- %4 = getelementptr inbounds i32, i32* %0, i64 1
- %5 = load i32, i32* %4, align 4
- %6 = add nsw i32 %3, %5
- ret i32 %6
+ %2 = load i32, ptr %0, align 4
+ %3 = getelementptr inbounds i32, ptr %0, i64 1
+ %4 = load i32, ptr %3, align 4
+ %5 = add nsw i32 %2, %4
+ ret i32 %5
}
define i32 @caller2(i32 %0, i32 %1) {
; CHECK-LABEL: define {{[^@]+}}@caller2
-; CHECK-SAME: (i32 [[P_0:%.*]], i32 [[P_1:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = alloca [2 x i32], align 4
-; CHECK-NEXT: [[PL_0:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP1]], i64 0, i64 0
-; CHECK-NEXT: store i32 [[P_0]], i32* [[PL_0]], align 4
-; CHECK-NEXT: [[PL_1:%.*]] = getelementptr inbounds i32, i32* [[PL_0]], i64 1
-; CHECK-NEXT: store i32 [[P_1]], i32* [[PL_1]], align 4
-; CHECK-NEXT: [[PL_2:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP1]], i64 0, i64 0
-; CHECK-NEXT: [[VAL_0:%.*]] = load i32, i32* [[PL_2]], align 4
-; CHECK-NEXT: [[PL_3:%.*]] = getelementptr i32, i32* [[PL_2]], i64 1
-; CHECK-NEXT: [[VAL_1:%.*]] = load i32, i32* [[PL_3]], align 4
-; CHECK-NEXT: [[RES:%.*]] = call i32 @callee2(i32 [[VAL_0]], i32 [[VAL_1]])
-; CHECK-NEXT: ret i32 [[RES]]
+; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
+; CHECK-NEXT: [[TMP3:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP3]], align 4
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[TMP3]], i64 1
+; CHECK-NEXT: store i32 [[TMP1]], ptr [[TMP4]], align 4
+; CHECK-NEXT: [[DOTVAL:%.*]] = load i32, ptr [[TMP3]], align 4
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP3]], i64 4
+; CHECK-NEXT: [[DOTVAL1:%.*]] = load i32, ptr [[TMP5]], align 4
+; CHECK-NEXT: [[TMP6:%.*]] = call i32 @callee2(i32 [[DOTVAL]], i32 [[DOTVAL1]])
+; CHECK-NEXT: ret i32 [[TMP6]]
;
%3 = alloca [2 x i32], align 4
- %4 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
- store i32 %0, i32* %4, align 4
- %5 = getelementptr inbounds i32, i32* %4, i64 1
- store i32 %1, i32* %5, align 4
- %6 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
- %7 = call i32 @callee2(i32* noundef %6)
- ret i32 %7
+ store i32 %0, ptr %3, align 4
+ %4 = getelementptr inbounds i32, ptr %3, i64 1
+ store i32 %1, ptr %4, align 4
+ %5 = call i32 @callee2(ptr noundef %3)
+ ret i32 %5
}
-define internal i32 @callee3(i32* noundef %0) {
+define internal i32 @callee3(ptr noundef %0) {
; CHECK-LABEL: define {{[^@]+}}@callee3
-; CHECK-SAME: (i32* noundef [[P_0:%.*]]) {
-; CHECK-NEXT: [[PL_0:%.*]] = getelementptr inbounds i32, i32* [[P_0]], i64 0
-; CHECK-NEXT: [[VAL_0:%.*]] = load i32, i32* [[PL_0]], align 4
-; CHECK-NEXT: [[PL_1:%.*]] = getelementptr inbounds i32, i32* [[P_0]], i64 1
-; CHECK-NEXT: [[VAL_1:%.*]] = load i32, i32* [[PL_1]], align 4
-; CHECK-NEXT: [[SUM_0:%.*]] = add nsw i32 [[VAL_0]], [[VAL_1]]
-; CHECK-NEXT: [[PL_2:%.*]] = getelementptr inbounds i32, i32* [[P_0]], i64 2
-; CHECK-NEXT: [[VAL_2:%.*]] = load i32, i32* [[PL_2]], align 4
-; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[SUM_0]], [[VAL_2]]
-; CHECK-NEXT: ret i32 [[RES]]
+; CHECK-SAME: (ptr noundef [[TMP0:%.*]]) {
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i64 1
+; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
+; CHECK-NEXT: [[TMP5:%.*]] = add nsw i32 [[TMP2]], [[TMP4]]
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[TMP0]], i64 2
+; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4
+; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP5]], [[TMP7]]
+; CHECK-NEXT: ret i32 [[TMP8]]
;
- %2 = getelementptr inbounds i32, i32* %0, i64 0
- %3 = load i32, i32* %2, align 4
- %4 = getelementptr inbounds i32, i32* %0, i64 1
- %5 = load i32, i32* %4, align 4
- %6 = add nsw i32 %3, %5
- %7 = getelementptr inbounds i32, i32* %0, i64 2
- %8 = load i32, i32* %7, align 4
- %9 = add nsw i32 %6, %8
- ret i32 %9
+ %2 = load i32, ptr %0, align 4
+ %3 = getelementptr inbounds i32, ptr %0, i64 1
+ %4 = load i32, ptr %3, align 4
+ %5 = add nsw i32 %2, %4
+ %6 = getelementptr inbounds i32, ptr %0, i64 2
+ %7 = load i32, ptr %6, align 4
+ %8 = add nsw i32 %5, %7
+ ret i32 %8
}
define i32 @caller3(i32 %0, i32 %1, i32 %2) {
; CHECK-LABEL: define {{[^@]+}}@caller3
-; CHECK-SAME: (i32 [[P_0:%.*]], i32 [[P_1:%.*]], i32 [[P_2:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = alloca [3 x i32], align 4
-; CHECK-NEXT: [[PL_0:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* [[TMP1]], i64 0, i64 0
-; CHECK-NEXT: store i32 [[P_0]], i32* [[PL_0]], align 4
-; CHECK-NEXT: [[PL_1:%.*]] = getelementptr inbounds i32, i32* [[PL_0]], i64 1
-; CHECK-NEXT: store i32 [[P_1]], i32* [[PL_1]], align 4
-; CHECK-NEXT: [[PL_2:%.*]] = getelementptr inbounds i32, i32* [[PL_1]], i64 1
-; CHECK-NEXT: store i32 [[P_2]], i32* [[PL_2]], align 4
-; CHECK-NEXT: [[PL_3:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* [[TMP1]], i64 0, i64 0
-; CHECK-NEXT: [[RES:%.*]] = call i32 @callee3(i32* noundef [[PL_3]])
-; CHECK-NEXT: ret i32 [[RES]]
+; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]]) {
+; CHECK-NEXT: [[TMP4:%.*]] = alloca [3 x i32], align 4
+; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP4]], align 4
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i64 1
+; CHECK-NEXT: store i32 [[TMP1]], ptr [[TMP5]], align 4
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i64 1
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP6]], align 4
+; CHECK-NEXT: [[TMP7:%.*]] = call i32 @callee3(ptr noundef [[TMP4]])
+; CHECK-NEXT: ret i32 [[TMP7]]
;
%4 = alloca [3 x i32], align 4
- %5 = getelementptr inbounds [3 x i32], [3 x i32]* %4, i64 0, i64 0
- store i32 %0, i32* %5, align 4
- %6 = getelementptr inbounds i32, i32* %5, i64 1
- store i32 %1, i32* %6, align 4
- %7 = getelementptr inbounds i32, i32* %6, i64 1
- store i32 %2, i32* %7, align 4
- %8 = getelementptr inbounds [3 x i32], [3 x i32]* %4, i64 0, i64 0
- %9 = call i32 @callee3(i32* noundef %8)
- ret i32 %9
+ store i32 %0, ptr %4, align 4
+ %5 = getelementptr inbounds i32, ptr %4, i64 1
+ store i32 %1, ptr %5, align 4
+ %6 = getelementptr inbounds i32, ptr %5, i64 1
+ store i32 %2, ptr %6, align 4
+ %7 = call i32 @callee3(ptr noundef %4)
+ ret i32 %7
}
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
declare void @use.i32(i32)
-declare void @use.p32(i32*)
+declare void @use.p32(ptr)
-define internal void @callee(i32* %p1, i32** %p2, i32** %p3, i32** %p4, i32** %p5, i32** %p6, i32** %p7) {
+define internal void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7) {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], i32* [[P2_0_VAL:%.*]], i32* [[P3_0_VAL:%.*]], i32* [[P4_0_VAL:%.*]], i32* [[P5_0_VAL:%.*]], i32* [[P6_0_VAL:%.*]], i32* [[P7_0_VAL:%.*]]) {
-; CHECK-NEXT: [[IS_NOT_NULL:%.*]] = icmp ne i32* [[P2_0_VAL]], null
+; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], ptr [[P2_0_VAL:%.*]], ptr [[P3_0_VAL:%.*]], ptr [[P4_0_VAL:%.*]], ptr [[P5_0_VAL:%.*]], ptr [[P6_0_VAL:%.*]], ptr [[P7_0_VAL:%.*]]) {
+; CHECK-NEXT: [[IS_NOT_NULL:%.*]] = icmp ne ptr [[P2_0_VAL]], null
; CHECK-NEXT: call void @llvm.assume(i1 [[IS_NOT_NULL]])
; CHECK-NEXT: call void @use.i32(i32 [[P1_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P2_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P3_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P4_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P5_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P6_0_VAL]])
-; CHECK-NEXT: call void @use.p32(i32* [[P7_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P2_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P3_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P4_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P5_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P6_0_VAL]])
+; CHECK-NEXT: call void @use.p32(ptr [[P7_0_VAL]])
; CHECK-NEXT: ret void
;
- %v1 = load i32, i32* %p1, !range !0
- %v2 = load i32*, i32** %p2, !nonnull !1
- %v3 = load i32*, i32** %p3, !dereferenceable !2
- %v4 = load i32*, i32** %p4, !dereferenceable_or_null !2
- %v5 = load i32*, i32** %p5, !align !3
- %v6 = load i32*, i32** %p6, !noundef !1
- %v7 = load i32*, i32** %p7, !nontemporal !4
+ %v1 = load i32, ptr %p1, !range !0
+ %v2 = load ptr, ptr %p2, !nonnull !1
+ %v3 = load ptr, ptr %p3, !dereferenceable !2
+ %v4 = load ptr, ptr %p4, !dereferenceable_or_null !2
+ %v5 = load ptr, ptr %p5, !align !3
+ %v6 = load ptr, ptr %p6, !noundef !1
+ %v7 = load ptr, ptr %p7, !nontemporal !4
call void @use.i32(i32 %v1)
- call void @use.p32(i32* %v2)
- call void @use.p32(i32* %v3)
- call void @use.p32(i32* %v4)
- call void @use.p32(i32* %v5)
- call void @use.p32(i32* %v6)
- call void @use.p32(i32* %v7)
+ call void @use.p32(ptr %v2)
+ call void @use.p32(ptr %v3)
+ call void @use.p32(ptr %v4)
+ call void @use.p32(ptr %v5)
+ call void @use.p32(ptr %v6)
+ call void @use.p32(ptr %v7)
ret void
}
-define void @caller(i32* %p1, i32** %p2, i32** %p3, i32** %p4, i32** %p5, i32** %p6, i32** %p7) {
+define void @caller(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i32* [[P1:%.*]], i32** [[P2:%.*]], i32** [[P3:%.*]], i32** [[P4:%.*]], i32** [[P5:%.*]], i32** [[P6:%.*]], i32** [[P7:%.*]]) {
-; CHECK-NEXT: [[P1_VAL:%.*]] = load i32, i32* [[P1]], align 4, !range [[RNG0:![0-9]+]]
-; CHECK-NEXT: [[P2_VAL:%.*]] = load i32*, i32** [[P2]], align 8, !nonnull !1
-; CHECK-NEXT: [[P3_VAL:%.*]] = load i32*, i32** [[P3]], align 8, !dereferenceable !2
-; CHECK-NEXT: [[P4_VAL:%.*]] = load i32*, i32** [[P4]], align 8, !dereferenceable_or_null !2
-; CHECK-NEXT: [[P5_VAL:%.*]] = load i32*, i32** [[P5]], align 8, !align !3
-; CHECK-NEXT: [[P6_VAL:%.*]] = load i32*, i32** [[P6]], align 8, !noundef !1
-; CHECK-NEXT: [[P7_VAL:%.*]] = load i32*, i32** [[P7]], align 8, !nontemporal !4
-; CHECK-NEXT: call void @callee(i32 [[P1_VAL]], i32* [[P2_VAL]], i32* [[P3_VAL]], i32* [[P4_VAL]], i32* [[P5_VAL]], i32* [[P6_VAL]], i32* [[P7_VAL]])
+; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]], ptr [[P4:%.*]], ptr [[P5:%.*]], ptr [[P6:%.*]], ptr [[P7:%.*]]) {
+; CHECK-NEXT: [[P1_VAL:%.*]] = load i32, ptr [[P1]], align 4, !range [[RNG0:![0-9]+]]
+; CHECK-NEXT: [[P2_VAL:%.*]] = load ptr, ptr [[P2]], align 8, !nonnull !1
+; CHECK-NEXT: [[P3_VAL:%.*]] = load ptr, ptr [[P3]], align 8, !dereferenceable !2
+; CHECK-NEXT: [[P4_VAL:%.*]] = load ptr, ptr [[P4]], align 8, !dereferenceable_or_null !2
+; CHECK-NEXT: [[P5_VAL:%.*]] = load ptr, ptr [[P5]], align 8, !align !3
+; CHECK-NEXT: [[P6_VAL:%.*]] = load ptr, ptr [[P6]], align 8, !noundef !1
+; CHECK-NEXT: [[P7_VAL:%.*]] = load ptr, ptr [[P7]], align 8, !nontemporal !4
+; CHECK-NEXT: call void @callee(i32 [[P1_VAL]], ptr [[P2_VAL]], ptr [[P3_VAL]], ptr [[P4_VAL]], ptr [[P5_VAL]], ptr [[P6_VAL]], ptr [[P7_VAL]])
; CHECK-NEXT: ret void
;
- call void @callee(i32* %p1, i32** %p2, i32** %p3, i32** %p4, i32** %p5, i32** %p6, i32** %p7)
+ call void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7)
ret void
}
-define internal i32* @callee_conditional(i1 %c, i32** dereferenceable(8) align 8 %p) {
+define internal ptr @callee_conditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
; CHECK-LABEL: define {{[^@]+}}@callee_conditional
-; CHECK-SAME: (i1 [[C:%.*]], i32* [[P_0_VAL:%.*]]) {
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P_0_VAL:%.*]]) {
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
-; CHECK-NEXT: [[IS_NOT_NULL:%.*]] = icmp ne i32* [[P_0_VAL]], null
+; CHECK-NEXT: [[IS_NOT_NULL:%.*]] = icmp ne ptr [[P_0_VAL]], null
; CHECK-NEXT: call void @llvm.assume(i1 [[IS_NOT_NULL]])
-; CHECK-NEXT: ret i32* [[P_0_VAL]]
+; CHECK-NEXT: ret ptr [[P_0_VAL]]
; CHECK: else:
-; CHECK-NEXT: ret i32* null
+; CHECK-NEXT: ret ptr null
;
br i1 %c, label %if, label %else
if:
- %v = load i32*, i32** %p, !nonnull !1
- ret i32* %v
+ %v = load ptr, ptr %p, !nonnull !1
+ ret ptr %v
else:
- ret i32* null
+ ret ptr null
}
-define void @caller_conditional(i1 %c, i32** %p) {
+define void @caller_conditional(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller_conditional
-; CHECK-SAME: (i1 [[C:%.*]], i32** [[P:%.*]]) {
-; CHECK-NEXT: [[P_VAL:%.*]] = load i32*, i32** [[P]], align 8
-; CHECK-NEXT: [[TMP1:%.*]] = call i32* @callee_conditional(i1 [[C]], i32* [[P_VAL]])
+; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_VAL:%.*]] = load ptr, ptr [[P]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee_conditional(i1 [[C]], ptr [[P_VAL]])
; CHECK-NEXT: ret void
;
- call i32* @callee_conditional(i1 %c, i32** %p)
+ call ptr @callee_conditional(i1 %c, ptr %p)
ret void
}
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
; CHECK-LABEL: define i32 @foo() #0 {
-; CHECK-NEXT: %.val = load <32 x half>, <32 x half>* undef, align 4
+; CHECK-NEXT: %.val = load <32 x half>, ptr undef, align 4
; CHECK-NEXT: call void @bar(<32 x half> %.val)
; CHECK-NEXT: ret i32 0
; CHECK-NEXT: }
; CHECK: attributes #0 = { uwtable "min-legal-vector-width"="512" }
define i32 @foo() #0 {
- call void @bar(<32 x half>* undef)
+ call void @bar(ptr undef)
ret i32 0
}
-define internal void @bar(<32 x half>*) #0 {
- %2 = load <32 x half>, <32 x half>* %0, align 4
+define internal void @bar(ptr) #0 {
+ %2 = load <32 x half>, ptr %0, align 4
ret void
}
%T = type { i32, i32, i32, i32 }
-define internal i32 @test(%T* %p) {
+define internal i32 @test(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@test
-; CHECK-SAME: (%T* [[P:%.*]]) {
-; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
-; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
-; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], ptr [[P]], i64 0, i32 3
+; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], ptr [[P]], i64 0, i32 2
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[A_GEP]], align 4
+; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_GEP]], align 4
; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[V]]
;
- %a.gep = getelementptr %T, %T* %p, i64 0, i32 3
- %b.gep = getelementptr %T, %T* %p, i64 0, i32 2
- %a = load i32, i32* %a.gep
- %b = load i32, i32* %b.gep
+ %a.gep = getelementptr %T, ptr %p, i64 0, i32 3
+ %b.gep = getelementptr %T, ptr %p, i64 0, i32 2
+ %a = load i32, ptr %a.gep
+ %b = load i32, ptr %b.gep
%v = add i32 %a, %b
ret i32 %v
}
-define i32 @caller(%T* %p) {
+define i32 @caller(ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (%T* [[P:%.*]]) {
-; CHECK-NEXT: [[V:%.*]] = musttail call i32 @test(%T* [[P]])
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT: [[V:%.*]] = musttail call i32 @test(ptr [[P]])
; CHECK-NEXT: ret i32 [[V]]
;
- %v = musttail call i32 @test(%T* %p)
+ %v = musttail call i32 @test(ptr %p)
ret i32 %v
}
; Don't promote arguments of musttail caller
-define i32 @foo(%T* %p, i32 %v) {
+define i32 @foo(ptr %p, i32 %v) {
; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (%T* [[P:%.*]], i32 [[V:%.*]]) {
+; CHECK-SAME: (ptr [[P:%.*]], i32 [[V:%.*]]) {
; CHECK-NEXT: ret i32 0
;
ret i32 0
}
-define internal i32 @test2(%T* %p, i32 %p2) {
+define internal i32 @test2(ptr %p, i32 %p2) {
; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (%T* [[P:%.*]], i32 [[P2:%.*]]) {
-; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
-; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
-; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; CHECK-SAME: (ptr [[P:%.*]], i32 [[P2:%.*]]) {
+; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], ptr [[P]], i64 0, i32 3
+; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], ptr [[P]], i64 0, i32 2
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[A_GEP]], align 4
+; CHECK-NEXT: [[B:%.*]] = load i32, ptr [[B_GEP]], align 4
; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
-; CHECK-NEXT: [[CA:%.*]] = musttail call i32 @foo(%T* undef, i32 [[V]])
+; CHECK-NEXT: [[CA:%.*]] = musttail call i32 @foo(ptr undef, i32 [[V]])
; CHECK-NEXT: ret i32 [[CA]]
;
- %a.gep = getelementptr %T, %T* %p, i64 0, i32 3
- %b.gep = getelementptr %T, %T* %p, i64 0, i32 2
- %a = load i32, i32* %a.gep
- %b = load i32, i32* %b.gep
+ %a.gep = getelementptr %T, ptr %p, i64 0, i32 3
+ %b.gep = getelementptr %T, ptr %p, i64 0, i32 2
+ %a = load i32, ptr %a.gep
+ %b = load i32, ptr %b.gep
%v = add i32 %a, %b
- %ca = musttail call i32 @foo(%T* undef, i32 %v)
+ %ca = musttail call i32 @foo(ptr undef, i32 %v)
ret i32 %ca
}
-define i32 @caller2(%T* %g) {
+define i32 @caller2(ptr %g) {
; CHECK-LABEL: define {{[^@]+}}@caller2
-; CHECK-SAME: (%T* [[G:%.*]]) {
-; CHECK-NEXT: [[V:%.*]] = call i32 @test2(%T* [[G]], i32 0)
+; CHECK-SAME: (ptr [[G:%.*]]) {
+; CHECK-NEXT: [[V:%.*]] = call i32 @test2(ptr [[G]], i32 0)
; CHECK-NEXT: ret i32 [[V]]
;
- %v = call i32 @test2(%T* %g, i32 0)
+ %v = call i32 @test2(ptr %g, i32 0)
ret i32 %v
}
define i32 @bar() {
; CHECK-LABEL: define {{[^@]+}}@bar() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32* @g)
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(ptr @g)
; CHECK-NEXT: ret i32 [[CALL]]
;
entry:
- %call = call i32 @foo(i32* @g)
+ %call = call i32 @foo(ptr @g)
ret i32 %call
}
-define internal i32 @foo(i32*) #0 {
+define internal i32 @foo(ptr) #0 {
; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: (ptr [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
; CHECK-NEXT: call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
;
entry:
- %call = call i32 @foo(i32* @g)
+ %call = call i32 @foo(ptr @g)
ret i32 %call
}
-define internal i32 @foo(i32*) {
+define internal i32 @foo(ptr) {
; CHECK-LABEL: define {{[^@]+}}@foo() addrspace(1) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
; RUN: opt -S -passes=debugify -o /dev/null < %s
target triple = "x86_64-pc-windows-msvc"
-define internal void @callee(i8*) {
+define internal void @callee(ptr) {
; CHECK-LABEL: define {{[^@]+}}@callee() {
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @thunk()
ret void
}
-define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
-; CHECK-LABEL: define {{[^@]+}}@test1() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test1() personality ptr @__CxxFrameHandler3 {
+; CHECK-LABEL: define {{[^@]+}}@test1() personality ptr @__CxxFrameHandler3 {
; CHECK-NEXT: entry:
; CHECK-NEXT: invoke void @thunk()
; CHECK-NEXT: to label [[OUT:%.*]] unwind label [[CPAD:%.*]]
cpad:
%pad = cleanuppad within none []
- call void @callee(i8* null) [ "funclet"(token %pad) ]
+ call void @callee(ptr null) [ "funclet"(token %pad) ]
cleanupret from %pad unwind to caller
}
define i32 @fn2() local_unnamed_addr {
; CHECK-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr {
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @b, align 4
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
-; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
-; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, i32* [[TMP3]], i64 -1
-; CHECK-NEXT: [[DOTVAL:%.*]] = load i32, i32* [[TMP4]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP3]], i64 -4
+; CHECK-NEXT: [[DOTVAL:%.*]] = load i32, ptr [[TMP4]], align 4
; CHECK-NEXT: call fastcc void @fn1(i32 [[DOTVAL]])
; CHECK-NEXT: ret i32 undef
;
- %1 = load i32, i32* @b, align 4
+ %1 = load i32, ptr @b, align 4
%2 = sext i32 %1 to i64
- %3 = inttoptr i64 %2 to i32*
- call fastcc void @fn1(i32* %3)
+ %3 = inttoptr i64 %2 to ptr
+ call fastcc void @fn1(ptr %3)
ret i32 undef
}
-define internal fastcc void @fn1(i32* nocapture readonly) unnamed_addr {
+define internal fastcc void @fn1(ptr nocapture readonly) unnamed_addr {
; CHECK-LABEL: define {{[^@]+}}@fn1
; CHECK-SAME: (i32 [[DOT_4_VAL:%.*]]) unnamed_addr {
-; CHECK-NEXT: store i32 [[DOT_4_VAL]], i32* @a, align 4
+; CHECK-NEXT: store i32 [[DOT_4_VAL]], ptr @a, align 4
; CHECK-NEXT: ret void
;
- %2 = getelementptr inbounds i32, i32* %0, i64 -1
- %3 = load i32, i32* %2, align 4
- store i32 %3, i32* @a, align 4
+ %2 = getelementptr inbounds i32, ptr %0, i64 -1
+ %3 = load i32, ptr %2, align 4
+ store i32 %3, ptr @a, align 4
ret void
}
; The %p argument should be removed, and the use of it in dbg.value should be
; changed to undef.
-%fun_t = type void (i16*)*
+%fun_t = type ptr
define void @foo() {
%a = alloca i16
- call void @bar(i16* %a)
+ call void @bar(ptr %a)
ret void
}
-define internal void @bar(i16* %p) {
+define internal void @bar(ptr %p) {
; CHECK-LABEL: define {{.*}}void @bar()
-; CHECK-NEXT: call void @llvm.dbg.value(metadata i16* undef, metadata !3, metadata !DIExpression()), !dbg !5
- call void @llvm.dbg.value(metadata i16* %p, metadata !3, metadata !DIExpression()), !dbg !5
+; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr undef, metadata !3, metadata !DIExpression()), !dbg !5
+ call void @llvm.dbg.value(metadata ptr %p, metadata !3, metadata !DIExpression()), !dbg !5
ret void
}
; This shouldn't get infinitely promoted.
-%S = type { %S* }
+%S = type { ptr }
define i32 @test_inf_promote_caller(i32 %arg) {
; CHECK-LABEL: define {{[^@]+}}@test_inf_promote_caller
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TEMP:%.*]] = alloca [[S:%.*]], align 8
; CHECK-NEXT: [[TEMP1:%.*]] = alloca [[S]], align 8
-; CHECK-NEXT: [[TEMP2:%.*]] = call i32 @test_inf_promote_callee(%S* [[TEMP]], %S* [[TEMP1]])
+; CHECK-NEXT: [[TEMP2:%.*]] = call i32 @test_inf_promote_callee(ptr [[TEMP]], ptr [[TEMP1]])
; CHECK-NEXT: ret i32 0
;
bb:
%temp = alloca %S
%temp1 = alloca %S
- %temp2 = call i32 @test_inf_promote_callee(%S* %temp, %S* %temp1)
+ %temp2 = call i32 @test_inf_promote_callee(ptr %temp, ptr %temp1)
ret i32 0
}
-define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) {
+define internal i32 @test_inf_promote_callee(ptr %arg, ptr %arg1) {
; CHECK-LABEL: define {{[^@]+}}@test_inf_promote_callee
-; CHECK-SAME: (%S* [[ARG:%.*]], %S* [[ARG1:%.*]]) {
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]]) {
; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr [[S:%.*]], %S* [[ARG1]], i32 0, i32 0
-; CHECK-NEXT: [[TEMP2:%.*]] = load %S*, %S** [[TEMP]], align 8
-; CHECK-NEXT: [[TEMP3:%.*]] = getelementptr [[S]], %S* [[ARG]], i32 0, i32 0
-; CHECK-NEXT: [[TEMP4:%.*]] = load %S*, %S** [[TEMP3]], align 8
-; CHECK-NEXT: [[TEMP5:%.*]] = call i32 @test_inf_promote_callee2(%S* [[TEMP4]], %S* [[TEMP2]])
+; CHECK-NEXT: [[TEMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
+; CHECK-NEXT: [[TEMP4:%.*]] = load ptr, ptr [[ARG]], align 8
+; CHECK-NEXT: [[TEMP5:%.*]] = call i32 @test_inf_promote_callee2(ptr [[TEMP4]], ptr [[TEMP2]])
; CHECK-NEXT: ret i32 0
;
bb:
- %temp = getelementptr %S, %S* %arg1, i32 0, i32 0
- %temp2 = load %S*, %S** %temp
- %temp3 = getelementptr %S, %S* %arg, i32 0, i32 0
- %temp4 = load %S*, %S** %temp3
- %temp5 = call i32 @test_inf_promote_callee2(%S* %temp4, %S* %temp2)
+ %temp2 = load ptr, ptr %arg1
+ %temp4 = load ptr, ptr %arg
+ %temp5 = call i32 @test_inf_promote_callee2(ptr %temp4, ptr %temp2)
ret i32 0
}
-define internal i32 @test_inf_promote_callee2(%S* %arg, %S* %arg1) {
+define internal i32 @test_inf_promote_callee2(ptr %arg, ptr %arg1) {
; CHECK-LABEL: define {{[^@]+}}@test_inf_promote_callee2
-; CHECK-SAME: (%S* [[ARG:%.*]], %S* [[ARG1:%.*]]) {
-; CHECK-NEXT: [[R:%.*]] = call i32 @test_inf_promote_callee(%S* [[ARG]], %S* [[ARG1]])
+; CHECK-SAME: (ptr [[ARG:%.*]], ptr [[ARG1:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = call i32 @test_inf_promote_callee(ptr [[ARG]], ptr [[ARG1]])
; CHECK-NEXT: ret i32 0
;
- %r = call i32 @test_inf_promote_callee(%S* %arg, %S* %arg1)
+ %r = call i32 @test_inf_promote_callee(ptr %arg, ptr %arg1)
ret i32 0
}
; CHECK-NEXT: ret void
;
%x = alloca i32
- store i32 42, i32* %x
- call void @promote_i32_ptr(i32* %x), !prof !0
+ store i32 42, ptr %x
+ call void @promote_i32_ptr(ptr %x), !prof !0
ret void
}
-define internal void @promote_i32_ptr(i32* %xp) !prof !1 {
+define internal void @promote_i32_ptr(ptr %xp) !prof !1 {
; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr
; CHECK-SAME: (i32 [[XP_0_VAL:%.*]]) !prof [[PROF1:![0-9]+]] {
; CHECK-NEXT: call void @use_i32(i32 [[XP_0_VAL]])
; CHECK-NEXT: ret void
;
- %x = load i32, i32* %xp
+ %x = load i32, ptr %xp
call void @use_i32(i32 %x)
ret void
}
; This testing case makes sure that we correctly transfer the tbaa tags from the
; original loads to the newly-created loads when promoting pointer arguments.
-@a = global i32* null, align 8
-@e = global i32** @a, align 8
+@a = global ptr null, align 8
+@e = global ptr @a, align 8
@g = global i32 0, align 4
@c = global i64 0, align 8
@d = global i8 0, align 1
-define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture readonly %p2) {
+define internal fastcc void @fn(ptr nocapture readonly %p1, ptr nocapture readonly %p2) {
; CHECK-LABEL: define {{[^@]+}}@fn
; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], i64 [[P2_0_VAL:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[P2_0_VAL]] to i32
; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[P1_0_VAL]] to i8
-; CHECK-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa [[TBAA0:![0-9]+]]
+; CHECK-NEXT: store i8 [[CONV1]], ptr @d, align 1, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: ret void
;
entry:
- %0 = load i64, i64* %p2, align 8, !tbaa !1
+ %0 = load i64, ptr %p2, align 8, !tbaa !1
%conv = trunc i64 %0 to i32
- %1 = load i32, i32* %p1, align 4, !tbaa !5
+ %1 = load i32, ptr %p1, align 4, !tbaa !5
%conv1 = trunc i32 %1 to i8
- store i8 %conv1, i8* @d, align 1, !tbaa !7
+ store i8 %conv1, ptr @d, align 1, !tbaa !7
ret void
}
define i32 @main() {
; CHECK-LABEL: define {{[^@]+}}@main() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa [[TBAA3:![0-9]+]]
-; CHECK-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA3]]
-; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA3]]
-; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA5:![0-9]+]]
-; CHECK-NEXT: [[G_VAL:%.*]] = load i32, i32* @g, align 4, !tbaa [[TBAA5]]
-; CHECK-NEXT: [[C_VAL:%.*]] = load i64, i64* @c, align 8, !tbaa [[TBAA7:![0-9]+]]
+; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr @e, align 8, !tbaa [[TBAA3:![0-9]+]]
+; CHECK-NEXT: store ptr @g, ptr [[TMP0]], align 8, !tbaa [[TBAA3]]
+; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @a, align 8, !tbaa [[TBAA3]]
+; CHECK-NEXT: store i32 1, ptr [[TMP1]], align 4, !tbaa [[TBAA5:![0-9]+]]
+; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @g, align 4, !tbaa [[TBAA5]]
+; CHECK-NEXT: [[C_VAL:%.*]] = load i64, ptr @c, align 8, !tbaa [[TBAA7:![0-9]+]]
; CHECK-NEXT: call fastcc void @fn(i32 [[G_VAL]], i64 [[C_VAL]])
; CHECK-NEXT: ret i32 0
;
entry:
- %0 = load i32**, i32*** @e, align 8, !tbaa !8
- store i32* @g, i32** %0, align 8, !tbaa !8
- %1 = load i32*, i32** @a, align 8, !tbaa !8
- store i32 1, i32* %1, align 4, !tbaa !5
- call fastcc void @fn(i32* @g, i64* @c)
+ %0 = load ptr, ptr @e, align 8, !tbaa !8
+ store ptr @g, ptr %0, align 8, !tbaa !8
+ %1 = load ptr, ptr @a, align 8, !tbaa !8
+ store i32 1, ptr %1, align 4, !tbaa !5
+ call fastcc void @fn(ptr @g, ptr @c)
ret i32 0
}
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
-define internal void @add({i32, i32}* %this, i32* sret(i32) %r) {
+define internal void @add(ptr %this, ptr sret(i32) %r) {
; CHECK-LABEL: define {{[^@]+}}@add
-; CHECK-SAME: (i32 [[THIS_0_VAL:%.*]], i32 [[THIS_4_VAL:%.*]], i32* noalias [[R:%.*]]) {
+; CHECK-SAME: (i32 [[THIS_0_VAL:%.*]], i32 [[THIS_4_VAL:%.*]], ptr noalias [[R:%.*]]) {
; CHECK-NEXT: [[AB:%.*]] = add i32 [[THIS_0_VAL]], [[THIS_4_VAL]]
-; CHECK-NEXT: store i32 [[AB]], i32* [[R]], align 4
+; CHECK-NEXT: store i32 [[AB]], ptr [[R]], align 4
; CHECK-NEXT: ret void
;
- %ap = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 0
- %bp = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 1
- %a = load i32, i32* %ap
- %b = load i32, i32* %bp
+ %ap = getelementptr {i32, i32}, ptr %this, i32 0, i32 0
+ %bp = getelementptr {i32, i32}, ptr %this, i32 0, i32 1
+ %a = load i32, ptr %ap
+ %b = load i32, ptr %bp
%ab = add i32 %a, %b
- store i32 %ab, i32* %r
+ store i32 %ab, ptr %r
ret void
}
; CHECK-LABEL: define {{[^@]+}}@f() {
; CHECK-NEXT: [[R:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[PAIR]], i64 0, i32 0
-; CHECK-NEXT: [[PAIR_VAL:%.*]] = load i32, i32* [[TMP1]], align 4
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[PAIR]], i64 0, i32 1
-; CHECK-NEXT: [[PAIR_VAL1:%.*]] = load i32, i32* [[TMP2]], align 4
-; CHECK-NEXT: call void @add(i32 [[PAIR_VAL]], i32 [[PAIR_VAL1]], i32* noalias [[R]])
+; CHECK-NEXT: [[PAIR_VAL:%.*]] = load i32, ptr [[PAIR]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PAIR]], i64 4
+; CHECK-NEXT: [[PAIR_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
+; CHECK-NEXT: call void @add(i32 [[PAIR_VAL]], i32 [[PAIR_VAL1]], ptr noalias [[R]])
; CHECK-NEXT: ret void
;
%r = alloca i32
%pair = alloca {i32, i32}
- call void @add({i32, i32}* %pair, i32* sret(i32) %r)
+ call void @add(ptr %pair, ptr sret(i32) %r)
ret void
}
; RUN: opt < %s -passes=argpromotion -S | FileCheck %s
; Store instructions are allowed users for byval arguments only.
-define internal void @callee(i32* %arg) nounwind {
+define internal void @callee(ptr %arg) nounwind {
; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32* [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: (ptr [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TEMP:%.*]] = load i32, i32* [[ARG]], align 4
+; CHECK-NEXT: [[TEMP:%.*]] = load i32, ptr [[ARG]], align 4
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[TEMP]], 1
-; CHECK-NEXT: store i32 [[SUM]], i32* [[ARG]], align 4
+; CHECK-NEXT: store i32 [[SUM]], ptr [[ARG]], align 4
; CHECK-NEXT: ret void
;
entry:
- %temp = load i32, i32* %arg, align 4
+ %temp = load i32, ptr %arg, align 4
%sum = add i32 %temp, 1
- store i32 %sum, i32* %arg, align 4
+ store i32 %sum, ptr %arg, align 4
ret void
}
-define i32 @caller(i32* %arg) nounwind {
+define i32 @caller(ptr %arg) nounwind {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i32* [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (ptr [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @callee(i32* [[ARG]]) #[[ATTR0]]
+; CHECK-NEXT: call void @callee(ptr [[ARG]]) #[[ATTR0]]
; CHECK-NEXT: ret i32 0
;
entry:
- call void @callee(i32* %arg) nounwind
+ call void @callee(ptr %arg) nounwind
ret i32 0
}
; Unused pointer argument should be removed from the function's signature
; while the used arguments should be promoted if they are pointers.
; The pass should not touch any unused non-pointer arguments.
-define internal i32 @callee(i1 %c, i1 %d, i32* %used, i32* %unused) nounwind {
+define internal i32 @callee(i1 %c, i1 %d, ptr %used, ptr %unused) nounwind {
; CHECK-LABEL: define {{[^@]+}}@callee
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], i32 [[USED_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
- %x = load i32, i32* %used, align 4
+ %x = load i32, ptr %used, align 4
br i1 %c, label %if, label %else
if:
; Unused byval argument should be removed from the function's signature
; while the used arguments should be promoted if they are pointers.
; The pass should not touch any unused non-pointer arguments.
-define internal i32 @callee_byval(i1 %c, i1 %d, i32* byval(i32) align 4 %used, i32* byval(i32) align 4 %unused) nounwind {
+define internal i32 @callee_byval(i1 %c, i1 %d, ptr byval(i32) align 4 %used, ptr byval(i32) align 4 %unused) nounwind {
; CHECK-LABEL: define {{[^@]+}}@callee_byval
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], i32 [[USED_VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
- %x = load i32, i32* %used, align 4
+ %x = load i32, ptr %used, align 4
br i1 %c, label %if, label %else
if:
ret i32 -1
}
-define i32 @caller(i1 %c, i1 %d, i32* %arg) nounwind {
+define i32 @caller(i1 %c, i1 %d, ptr %arg) nounwind {
; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], i32* [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], ptr [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARG_VAL_0:%.*]] = load i32, i32* [[ARG]], align 4
+; CHECK-NEXT: [[ARG_VAL_0:%.*]] = load i32, ptr [[ARG]], align 4
; CHECK-NEXT: [[RES_0:%.*]] = call i32 @callee_byval(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_0]]) #[[ATTR0]]
-; CHECK-NEXT: [[ARG_VAL_1:%.*]] = load i32, i32* [[ARG]], align 4
+; CHECK-NEXT: [[ARG_VAL_1:%.*]] = load i32, ptr [[ARG]], align 4
; CHECK-NEXT: [[RES_1:%.*]] = call i32 @callee(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_1]]) #[[ATTR0]]
; CHECK-NEXT: ret i32 1
;
entry:
- call i32 @callee_byval(i1 %c, i1 %d, i32* byval(i32) align 4 %arg, i32* byval(i32) align 4 %arg) nounwind
- call i32 @callee(i1 %c, i1 %d, i32* %arg, i32* %arg) nounwind
+ call i32 @callee_byval(i1 %c, i1 %d, ptr byval(i32) align 4 %arg, ptr byval(i32) align 4 %arg) nounwind
+ call i32 @callee(i1 %c, i1 %d, ptr %arg, ptr %arg) nounwind
ret i32 1
}
target triple = "x86_64-unknown-linux-gnu"
%struct.tt0 = type { i64, i64 }
-%struct.__va_list_tag = type { i32, i32, i8*, i8* }
+%struct.__va_list_tag = type { i32, i32, ptr, ptr }
@t45 = internal global %struct.tt0 { i64 1335139741, i64 438042995 }, align 8
; Function Attrs: nounwind uwtable
-define i32 @main(i32 %argc, i8** nocapture readnone %argv) #0 {
+define i32 @main(i32 %argc, ptr nocapture readnone %argv) #0 {
; CHECK-LABEL: define {{[^@]+}}@main
-; CHECK-SAME: (i32 [[ARGC:%.*]], i8** nocapture readnone [[ARGV:%.*]]) {
+; CHECK-SAME: (i32 [[ARGC:%.*]], ptr nocapture readnone [[ARGV:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* byval([[STRUCT_TT0:%.*]]) align 8 @t45)
+; CHECK-NEXT: tail call void (ptr, ptr, ptr, ptr, ptr, ...) @callee_t0f(ptr undef, ptr undef, ptr undef, ptr undef, ptr undef, ptr byval([[STRUCT_TT0:%.*]]) align 8 @t45)
; CHECK-NEXT: ret i32 0
;
entry:
- tail call void (i8*, i8*, i8*, i8*, i8*, ...) @callee_t0f(i8* undef, i8* undef, i8* undef, i8* undef, i8* undef, %struct.tt0* byval(%struct.tt0) align 8 @t45)
+ tail call void (ptr, ptr, ptr, ptr, ptr, ...) @callee_t0f(ptr undef, ptr undef, ptr undef, ptr undef, ptr undef, ptr byval(%struct.tt0) align 8 @t45)
ret i32 0
}
; Function Attrs: nounwind uwtable
-define internal void @callee_t0f(i8* nocapture readnone %tp13, i8* nocapture readnone %tp14, i8* nocapture readnone %tp15, i8* nocapture readnone %tp16, i8* nocapture readnone %tp17, ...) {
+define internal void @callee_t0f(ptr nocapture readnone %tp13, ptr nocapture readnone %tp14, ptr nocapture readnone %tp15, ptr nocapture readnone %tp16, ptr nocapture readnone %tp17, ...) {
; CHECK-LABEL: define {{[^@]+}}@callee_t0f
-; CHECK-SAME: (i8* nocapture readnone [[TP13:%.*]], i8* nocapture readnone [[TP14:%.*]], i8* nocapture readnone [[TP15:%.*]], i8* nocapture readnone [[TP16:%.*]], i8* nocapture readnone [[TP17:%.*]], ...) {
+; CHECK-SAME: (ptr nocapture readnone [[TP13:%.*]], ptr nocapture readnone [[TP14:%.*]], ptr nocapture readnone [[TP15:%.*]], ptr nocapture readnone [[TP16:%.*]], ptr nocapture readnone [[TP17:%.*]], ...) {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret void
;
; Make sure volatile and atomic loads are not promoted.
-define internal i32 @callee_volatile(i32* %p) {
+define internal i32 @callee_volatile(ptr %p) {
; CHECK-LABEL: @callee_volatile(
-; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
+; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4
; CHECK-NEXT: ret i32 [[V]]
;
- %v = load volatile i32, i32* %p
+ %v = load volatile i32, ptr %p
ret i32 %v
}
-define void @caller_volatile(i32* %p) {
+define void @caller_volatile(ptr %p) {
; CHECK-LABEL: @caller_volatile(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_volatile(i32* [[P:%.*]])
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_volatile(ptr [[P:%.*]])
; CHECK-NEXT: ret void
;
- call i32 @callee_volatile(i32* %p)
+ call i32 @callee_volatile(ptr %p)
ret void
}
-define internal i32 @callee_atomic(i32* %p) {
+define internal i32 @callee_atomic(ptr %p) {
; CHECK-LABEL: @callee_atomic(
-; CHECK-NEXT: [[V:%.*]] = load atomic i32, i32* [[P:%.*]] seq_cst, align 4
+; CHECK-NEXT: [[V:%.*]] = load atomic i32, ptr [[P:%.*]] seq_cst, align 4
; CHECK-NEXT: ret i32 [[V]]
;
- %v = load atomic i32, i32* %p seq_cst, align 4
+ %v = load atomic i32, ptr %p seq_cst, align 4
ret i32 %v
}
-define void @caller_atomic(i32* %p) {
+define void @caller_atomic(ptr %p) {
; CHECK-LABEL: @caller_atomic(
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_atomic(i32* [[P:%.*]])
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_atomic(ptr [[P:%.*]])
; CHECK-NEXT: ret void
;
- call i32 @callee_atomic(i32* %p)
+ call i32 @callee_atomic(ptr %p)
ret void
}