[llvm] 82cf72a - [InstCombine] Convert some tests to opaque pointers (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 3 08:20:50 PST 2023


Author: Nikita Popov
Date: 2023-01-03T17:20:43+01:00
New Revision: 82cf72a83b0823b9426f280f8620daab67c221e4

URL: https://github.com/llvm/llvm-project/commit/82cf72a83b0823b9426f280f8620daab67c221e4
DIFF: https://github.com/llvm/llvm-project/commit/82cf72a83b0823b9426f280f8620daab67c221e4.diff

LOG: [InstCombine] Convert some tests to opaque pointers (NFC)

These involved regenerating test checks. There are two significant
differences here:

1. With typed pointers we sometimes swapped gep and addrspacecast,
   as a side-effect of other transforms. However, the current
   direction is likely undesirable, and we should canonicalize in
   the reverse direction instead (gep of ac, instead of ac of gep).
   This should be done after typed pointers are removed, to avoid
   conflicting transforms.

2. The "descaling" optimization isn't really compatible with
   opaque pointers. This will be addressed longer-term by moving
   away from type-based GEP, at which point the form with explicit
   multiplications will be the canonical one.

Added: 
    

Modified: 
    llvm/test/Transforms/InstCombine/cast.ll
    llvm/test/Transforms/InstCombine/gep-addrspace.ll
    llvm/test/Transforms/InstCombine/gep-custom-dl.ll
    llvm/test/Transforms/InstCombine/gep-vector.ll
    llvm/test/Transforms/InstCombine/getelementptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
index 3fafbd69e032..cd3b032d739d 100644
--- a/llvm/test/Transforms/InstCombine/cast.ll
+++ b/llvm/test/Transforms/InstCombine/cast.ll
@@ -110,51 +110,48 @@ define i16 @test10(i16 %A) {
 
 declare void @varargs(i32, ...)
 
-define void @test11(i32* %P) {
+define void @test11(ptr %P) {
 ; ALL-LABEL: @test11(
-; ALL-NEXT:    call void (i32, ...) @varargs(i32 5, i32* [[P:%.*]])
+; ALL-NEXT:    call void (i32, ...) @varargs(i32 5, ptr [[P:%.*]])
 ; ALL-NEXT:    ret void
 ;
-  %c = bitcast i32* %P to i16*
-  call void (i32, ...) @varargs( i32 5, i16* %c )
+  call void (i32, ...) @varargs( i32 5, ptr %P )
   ret void
 }
 
 declare i32 @__gxx_personality_v0(...)
-define void @test_invoke_vararg_cast(i32* %a, i32* %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+define void @test_invoke_vararg_cast(ptr %a, ptr %b) personality ptr @__gxx_personality_v0 {
 ; ALL-LABEL: @test_invoke_vararg_cast(
 ; ALL-NEXT:  entry:
-; ALL-NEXT:    invoke void (i32, ...) @varargs(i32 1, i32* [[B:%.*]], i32* [[A:%.*]])
+; ALL-NEXT:    invoke void (i32, ...) @varargs(i32 1, ptr [[B:%.*]], ptr [[A:%.*]])
 ; ALL-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
 ; ALL:       invoke.cont:
 ; ALL-NEXT:    ret void
 ; ALL:       lpad:
-; ALL-NEXT:    [[TMP0:%.*]] = landingpad { i8*, i32 }
+; ALL-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
 ; ALL-NEXT:    cleanup
 ; ALL-NEXT:    ret void
 ;
 entry:
-  %0 = bitcast i32* %b to i8*
-  %1 = bitcast i32* %a to i64*
-  invoke void (i32, ...) @varargs(i32 1, i8* %0, i64* %1)
+  invoke void (i32, ...) @varargs(i32 1, ptr %b, ptr %a)
   to label %invoke.cont unwind label %lpad
 
 invoke.cont:
   ret void
 
 lpad:
-  %2 = landingpad { i8*, i32 }
+  %0 = landingpad { ptr, i32 }
   cleanup
   ret void
 }
 
-define i8* @test13(i64 %A) {
+define ptr @test13(i64 %A) {
 ; ALL-LABEL: @test13(
-; ALL-NEXT:    [[C:%.*]] = getelementptr [32832 x i8], [32832 x i8]* @inbuf, i64 0, i64 [[A:%.*]]
-; ALL-NEXT:    ret i8* [[C]]
+; ALL-NEXT:    [[C:%.*]] = getelementptr [0 x i8], ptr @inbuf, i64 0, i64 [[A:%.*]]
+; ALL-NEXT:    ret ptr [[C]]
 ;
-  %c = getelementptr [0 x i8], [0 x i8]* bitcast ([32832 x i8]* @inbuf to [0 x i8]*), i64 0, i64 %A
-  ret i8* %c
+  %c = getelementptr [0 x i8], ptr @inbuf, i64 0, i64 %A
+  ret ptr %c
 }
 
 define i1 @test14(i8 %A) {
@@ -175,12 +172,12 @@ define i1 @test14(i8 %A) {
 ;        ret bool %X
 ;}
 
-define i1 @test16(i32* %P) {
+define i1 @test16(ptr %P) {
 ; ALL-LABEL: @test16(
-; ALL-NEXT:    [[C:%.*]] = icmp ne i32* [[P:%.*]], null
+; ALL-NEXT:    [[C:%.*]] = icmp ne ptr [[P:%.*]], null
 ; ALL-NEXT:    ret i1 [[C]]
 ;
-  %c = icmp ne i32* %P, null
+  %c = icmp ne ptr %P, null
   ret i1 %c
 }
 
@@ -294,22 +291,18 @@ define i32 @test26(float %F) {
   ret i32 %D
 }
 
-define [4 x float]* @test27([9 x [4 x float]]* %A) {
+define ptr @test27(ptr %A) {
 ; ALL-LABEL: @test27(
-; ALL-NEXT:    [[C:%.*]] = getelementptr [9 x [4 x float]], [9 x [4 x float]]* [[A:%.*]], i64 0, i64 0
-; ALL-NEXT:    ret [4 x float]* [[C]]
+; ALL-NEXT:    ret ptr [[A:%.*]]
 ;
-  %c = bitcast [9 x [4 x float]]* %A to [4 x float]*
-  ret [4 x float]* %c
+  ret ptr %A
 }
 
-define float* @test28([4 x float]* %A) {
+define ptr @test28(ptr %A) {
 ; ALL-LABEL: @test28(
-; ALL-NEXT:    [[C:%.*]] = getelementptr [4 x float], [4 x float]* [[A:%.*]], i64 0, i64 0
-; ALL-NEXT:    ret float* [[C]]
+; ALL-NEXT:    ret ptr [[A:%.*]]
 ;
-  %c = bitcast [4 x float]* %A to float*
-  ret float* %c
+  ret ptr %A
 }
 
 define i32 @test29(i32 %c1, i32 %c2) {
@@ -533,33 +526,29 @@ define <2 x i16> @test40vec_undef(<2 x i16> %a) {
 }
 
 ; PR1263
-define i32* @test41(i32* %t1) {
+define ptr @test41(ptr %t1) {
 ; ALL-LABEL: @test41(
-; ALL-NEXT:    ret i32* [[T1:%.*]]
+; ALL-NEXT:    ret ptr [[T1:%.*]]
 ;
-  %t64 = bitcast i32* %t1 to { i32 }*
-  %t65 = getelementptr { i32 }, { i32 }* %t64, i32 0, i32 0
-  ret i32* %t65
+  ret ptr %t1
 }
 
-define i32 addrspace(1)* @test41_addrspacecast_smaller(i32* %t1) {
+define ptr addrspace(1) @test41_addrspacecast_smaller(ptr %t1) {
 ; ALL-LABEL: @test41_addrspacecast_smaller(
-; ALL-NEXT:    [[T65:%.*]] = addrspacecast i32* [[T1:%.*]] to i32 addrspace(1)*
-; ALL-NEXT:    ret i32 addrspace(1)* [[T65]]
+; ALL-NEXT:    [[T64:%.*]] = addrspacecast ptr [[T1:%.*]] to ptr addrspace(1)
+; ALL-NEXT:    ret ptr addrspace(1) [[T64]]
 ;
-  %t64 = addrspacecast i32* %t1 to { i32 } addrspace(1)*
-  %t65 = getelementptr { i32 }, { i32 } addrspace(1)* %t64, i32 0, i32 0
-  ret i32 addrspace(1)* %t65
+  %t64 = addrspacecast ptr %t1 to ptr addrspace(1)
+  ret ptr addrspace(1) %t64
 }
 
-define i32* @test41_addrspacecast_larger(i32 addrspace(1)* %t1) {
+define ptr @test41_addrspacecast_larger(ptr addrspace(1) %t1) {
 ; ALL-LABEL: @test41_addrspacecast_larger(
-; ALL-NEXT:    [[T65:%.*]] = addrspacecast i32 addrspace(1)* [[T1:%.*]] to i32*
-; ALL-NEXT:    ret i32* [[T65]]
+; ALL-NEXT:    [[T64:%.*]] = addrspacecast ptr addrspace(1) [[T1:%.*]] to ptr
+; ALL-NEXT:    ret ptr [[T64]]
 ;
-  %t64 = addrspacecast i32 addrspace(1)* %t1 to { i32 }*
-  %t65 = getelementptr { i32 }, { i32 }* %t64, i32 0, i32 0
-  ret i32* %t65
+  %t64 = addrspacecast ptr addrspace(1) %t1 to ptr
+  ret ptr %t64
 }
 
 define i32 @test42(i32 %X) {
@@ -685,8 +674,8 @@ define i64 @test49(i64 %A) {
 define i64 @test50(i64 %x) {
 ; ALL-LABEL: @test50(
 ; ALL-NEXT:    [[TMP1:%.*]] = shl i64 [[X:%.*]], 30
-; ALL-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], -4294967296
-; ALL-NEXT:    [[E:%.*]] = ashr i64 [[TMP2]], 32
+; ALL-NEXT:    [[SEXT:%.*]] = add i64 [[TMP1]], -4294967296
+; ALL-NEXT:    [[E:%.*]] = ashr i64 [[SEXT]], 32
 ; ALL-NEXT:    ret i64 [[E]]
 ;
   %a = lshr i64 %x, 2
@@ -989,215 +978,202 @@ define i1 @test67(i1 %a, i32 %b) {
 
 %s = type { i32, i32, i16 }
 
-define %s @test68(%s *%p, i64 %i) {
+define %s @test68(ptr %p, i64 %i) {
 ; ALL-LABEL: @test68(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], %s* [[P:%.*]], i64 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul i64 [[I:%.*]], 12
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul i64 %i, 12
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to %s*
-  %l = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o
+  %l = load %s, ptr %pp
   ret %s %l
 }
 
 ; addrspacecasts should be eliminated.
-define %s @test68_addrspacecast(%s* %p, i64 %i) {
+define %s @test68_addrspacecast(ptr %p, i64 %i) {
 ; ALL-LABEL: @test68_addrspacecast(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], %s* [[P:%.*]], i64 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul i64 [[I:%.*]], 12
+; ALL-NEXT:    [[Q:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(2)
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(2) [[Q]], i64 [[O]]
+; ALL-NEXT:    [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[R]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul i64 %i, 12
-  %q = addrspacecast %s* %p to i8 addrspace(2)*
-  %pp = getelementptr inbounds i8, i8 addrspace(2)* %q, i64 %o
-  %r = addrspacecast i8 addrspace(2)* %pp to %s*
-  %l = load %s, %s* %r
+  %q = addrspacecast ptr %p to ptr addrspace(2)
+  %pp = getelementptr inbounds i8, ptr addrspace(2) %q, i64 %o
+  %r = addrspacecast ptr addrspace(2) %pp to ptr
+  %l = load %s, ptr %r
   ret %s %l
 }
 
-define %s @test68_addrspacecast_2(%s* %p, i64 %i) {
+define %s @test68_addrspacecast_2(ptr %p, i64 %i) {
 ; ALL-LABEL: @test68_addrspacecast_2(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], %s* [[P:%.*]], i64 [[I:%.*]]
-; ALL-NEXT:    [[R:%.*]] = addrspacecast %s* [[PP1]] to [[S]] addrspace(1)*
-; ALL-NEXT:    [[L:%.*]] = load [[S]], [[S]] addrspace(1)* [[R]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul i64 [[I:%.*]], 12
+; ALL-NEXT:    [[Q:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(2)
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(2) [[Q]], i64 [[O]]
+; ALL-NEXT:    [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(1)
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr addrspace(1) [[R]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul i64 %i, 12
-  %q = addrspacecast %s* %p to i8 addrspace(2)*
-  %pp = getelementptr inbounds i8, i8 addrspace(2)* %q, i64 %o
-  %r = addrspacecast i8 addrspace(2)* %pp to %s addrspace(1)*
-  %l = load %s, %s addrspace(1)* %r
+  %q = addrspacecast ptr %p to ptr addrspace(2)
+  %pp = getelementptr inbounds i8, ptr addrspace(2) %q, i64 %o
+  %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(1)
+  %l = load %s, ptr addrspace(1) %r
   ret %s %l
 }
 
-define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
+define %s @test68_as1(ptr addrspace(1) %p, i32 %i) {
 ; ALL-LABEL: @test68_as1(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], [[S]] addrspace(1)* [[P:%.*]], i32 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], [[S]] addrspace(1)* [[PP1]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul i32 [[I:%.*]], 12
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[P:%.*]], i32 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr addrspace(1) [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul i32 %i, 12
-  %q = bitcast %s addrspace(1)* %p to i8 addrspace(1)*
-  %pp = getelementptr inbounds i8, i8 addrspace(1)* %q, i32 %o
-  %r = bitcast i8 addrspace(1)* %pp to %s addrspace(1)*
-  %l = load %s, %s addrspace(1)* %r
+  %pp = getelementptr inbounds i8, ptr addrspace(1) %p, i32 %o
+  %l = load %s, ptr addrspace(1) %pp
   ret %s %l
 }
 
-define double @test69(double *%p, i64 %i) {
+define double @test69(ptr %p, i64 %i) {
 ; ALL-LABEL: @test69(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr inbounds double, double* [[P:%.*]], i64 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[O:%.*]] = shl nsw i64 [[I:%.*]], 3
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %o = shl nsw i64 %i, 3
-  %q = bitcast double* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define %s @test70(%s *%p, i64 %i) {
+define %s @test70(ptr %p, i64 %i) {
 ; ALL-LABEL: @test70(
-; ALL-NEXT:    [[O:%.*]] = mul nsw i64 [[I:%.*]], 3
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr inbounds [[S:%.*]], %s* [[P:%.*]], i64 [[O]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul nsw i64 [[I:%.*]], 36
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul nsw i64 %i, 36
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to %s*
-  %l = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o
+  %l = load %s, ptr %pp
   ret %s %l
 }
 
-define double @test71(double *%p, i64 %i) {
+define double @test71(ptr %p, i64 %i) {
 ; ALL-LABEL: @test71(
-; ALL-NEXT:    [[O:%.*]] = shl i64 [[I:%.*]], 2
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr double, double* [[P:%.*]], i64 [[O]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[O:%.*]] = shl i64 [[I:%.*]], 5
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %o = shl i64 %i, 5
-  %q = bitcast double* %p to i8*
-  %pp = getelementptr i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr i8, ptr %p, i64 %o
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define double @test72(double *%p, i32 %i) {
+define double @test72(ptr %p, i32 %i) {
 ; ALL-LABEL: @test72(
-; ALL-NEXT:    [[O:%.*]] = sext i32 [[I:%.*]] to i64
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr inbounds double, double* [[P:%.*]], i64 [[O]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[SO:%.*]] = shl nsw i32 [[I:%.*]], 3
+; ALL-NEXT:    [[O:%.*]] = sext i32 [[SO]] to i64
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %so = shl nsw i32 %i, 3
   %o = sext i32 %so to i64
-  %q = bitcast double* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define double @test73(double *%p, i128 %i) {
+define double @test73(ptr %p, i128 %i) {
 ; ALL-LABEL: @test73(
 ; ALL-NEXT:    [[I_TR:%.*]] = trunc i128 [[I:%.*]] to i64
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr double, double* [[P:%.*]], i64 [[I_TR]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[O:%.*]] = shl i64 [[I_TR]], 3
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %lo = shl nsw i128 %i, 3
   %o = trunc i128 %lo to i64
-  %q = bitcast double* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define double @test74(double *%p, i64 %i) {
+define double @test74(ptr %p, i64 %i) {
 ; ALL-LABEL: @test74(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr inbounds double, double* [[P:%.*]], i64 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[I:%.*]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
-  %q = bitcast double* %p to i64*
-  %pp = getelementptr inbounds i64, i64* %q, i64 %i
-  %r = bitcast i64* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr inbounds i64, ptr %p, i64 %i
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define i32* @test75(i32* %p, i32 %x) {
+define ptr @test75(ptr %p, i32 %x) {
 ; ALL-LABEL: @test75(
 ; ALL-NEXT:    [[Y:%.*]] = shl i32 [[X:%.*]], 3
 ; ALL-NEXT:    [[Z:%.*]] = sext i32 [[Y]] to i64
-; ALL-NEXT:    [[Q:%.*]] = bitcast i32* [[P:%.*]] to i8*
-; ALL-NEXT:    [[R:%.*]] = getelementptr i8, i8* [[Q]], i64 [[Z]]
-; ALL-NEXT:    [[S:%.*]] = bitcast i8* [[R]] to i32*
-; ALL-NEXT:    ret i32* [[S]]
+; ALL-NEXT:    [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Z]]
+; ALL-NEXT:    ret ptr [[R]]
 ;
   %y = shl i32 %x, 3
   %z = sext i32 %y to i64
-  %q = bitcast i32* %p to i8*
-  %r = getelementptr i8, i8* %q, i64 %z
-  %s = bitcast i8* %r to i32*
-  ret i32* %s
+  %r = getelementptr i8, ptr %p, i64 %z
+  ret ptr %r
 }
 
-define %s @test76(%s *%p, i64 %i, i64 %j) {
+define %s @test76(ptr %p, i64 %i, i64 %j) {
 ; ALL-LABEL: @test76(
-; ALL-NEXT:    [[O2:%.*]] = mul i64 [[I:%.*]], [[J:%.*]]
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], %s* [[P:%.*]], i64 [[O2]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[O:%.*]] = mul i64 [[I:%.*]], 12
+; ALL-NEXT:    [[O2:%.*]] = mul nsw i64 [[O]], [[J:%.*]]
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O2]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul i64 %i, 12
   %o2 = mul nsw i64 %o, %j
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o2
-  %r = bitcast i8* %pp to %s*
-  %l = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o2
+  %l = load %s, ptr %pp
   ret %s %l
 }
 
-define %s @test77(%s *%p, i64 %i, i64 %j) {
+define %s @test77(ptr %p, i64 %i, i64 %j) {
 ; ALL-LABEL: @test77(
-; ALL-NEXT:    [[O:%.*]] = mul nsw i64 [[I:%.*]], 3
+; ALL-NEXT:    [[O:%.*]] = mul nsw i64 [[I:%.*]], 36
 ; ALL-NEXT:    [[O2:%.*]] = mul nsw i64 [[O]], [[J:%.*]]
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr inbounds [[S:%.*]], %s* [[P:%.*]], i64 [[O2]]
-; ALL-NEXT:    [[L:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[O2]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %o = mul nsw i64 %i, 36
   %o2 = mul nsw i64 %o, %j
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %o2
-  %r = bitcast i8* %pp to %s*
-  %l = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %o2
+  %l = load %s, ptr %pp
   ret %s %l
 }
 
-define %s @test78(%s *%p, i64 %i, i64 %j, i32 %k, i32 %l, i128 %m, i128 %n) {
+define %s @test78(ptr %p, i64 %i, i64 %j, i32 %k, i32 %l, i128 %m, i128 %n) {
 ; ALL-LABEL: @test78(
-; ALL-NEXT:    [[A:%.*]] = mul nsw i32 [[K:%.*]], 3
+; ALL-NEXT:    [[A:%.*]] = mul nsw i32 [[K:%.*]], 36
 ; ALL-NEXT:    [[B:%.*]] = mul nsw i32 [[A]], [[L:%.*]]
 ; ALL-NEXT:    [[C:%.*]] = sext i32 [[B]] to i128
 ; ALL-NEXT:    [[D:%.*]] = mul nsw i128 [[C]], [[M:%.*]]
 ; ALL-NEXT:    [[E:%.*]] = mul i128 [[D]], [[N:%.*]]
 ; ALL-NEXT:    [[F:%.*]] = trunc i128 [[E]] to i64
-; ALL-NEXT:    [[G:%.*]] = mul i64 [[F]], [[I:%.*]]
-; ALL-NEXT:    [[H:%.*]] = mul i64 [[G]], [[J:%.*]]
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [[S:%.*]], %s* [[P:%.*]], i64 [[H]]
-; ALL-NEXT:    [[LOAD:%.*]] = load [[S]], %s* [[PP1]], align 4
+; ALL-NEXT:    [[G:%.*]] = mul nsw i64 [[F]], [[I:%.*]]
+; ALL-NEXT:    [[H:%.*]] = mul nsw i64 [[G]], [[J:%.*]]
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[H]]
+; ALL-NEXT:    [[LOAD:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[LOAD]]
 ;
   %a = mul nsw i32 %k, 36
@@ -1208,108 +1184,103 @@ define %s @test78(%s *%p, i64 %i, i64 %j, i32 %k, i32 %l, i128 %m, i128 %n) {
   %f = trunc i128 %e to i64
   %g = mul nsw i64 %f, %i
   %h = mul nsw i64 %g, %j
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i64 %h
-  %r = bitcast i8* %pp to %s*
-  %load = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i64 %h
+  %load = load %s, ptr %pp
   ret %s %load
 }
 
-define %s @test79(%s *%p, i64 %i, i32 %j) {
+define %s @test79(ptr %p, i64 %i, i32 %j) {
 ; ALL-LABEL: @test79(
 ; ALL-NEXT:    [[TMP1:%.*]] = trunc i64 [[I:%.*]] to i32
 ; ALL-NEXT:    [[B:%.*]] = mul i32 [[TMP1]], 36
 ; ALL-NEXT:    [[C:%.*]] = mul i32 [[B]], [[J:%.*]]
-; ALL-NEXT:    [[Q:%.*]] = bitcast %s* [[P:%.*]] to i8*
 ; ALL-NEXT:    [[TMP2:%.*]] = sext i32 [[C]] to i64
-; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, i8* [[Q]], i64 [[TMP2]]
-; ALL-NEXT:    [[R:%.*]] = bitcast i8* [[PP]] to %s*
-; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], %s* [[R]], align 4
+; ALL-NEXT:    [[PP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[TMP2]]
+; ALL-NEXT:    [[L:%.*]] = load [[S:%.*]], ptr [[PP]], align 4
 ; ALL-NEXT:    ret [[S]] [[L]]
 ;
   %a = mul nsw i64 %i, 36
   %b = trunc i64 %a to i32
   %c = mul i32 %b, %j
-  %q = bitcast %s* %p to i8*
-  %pp = getelementptr inbounds i8, i8* %q, i32 %c
-  %r = bitcast i8* %pp to %s*
-  %l = load %s, %s* %r
+  %pp = getelementptr inbounds i8, ptr %p, i32 %c
+  %l = load %s, ptr %pp
   ret %s %l
 }
 
-define double @test80([100 x double]* %p, i32 %i) {
+define double @test80(ptr %p, i32 %i) {
 ; ALL-LABEL: @test80(
-; ALL-NEXT:    [[TMP1:%.*]] = sext i32 [[I:%.*]] to i64
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [100 x double], [100 x double]* [[P:%.*]], i64 0, i64 [[TMP1]]
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[PP1]], align 8
+; ALL-NEXT:    [[T:%.*]] = shl nsw i32 [[I:%.*]], 3
+; ALL-NEXT:    [[TMP1:%.*]] = sext i32 [[T]] to i64
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %t = shl nsw i32 %i, 3
-  %q = bitcast [100 x double]* %p to i8*
-  %pp = getelementptr i8, i8* %q, i32 %t
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr i8, ptr %p, i32 %t
+  %l = load double, ptr %pp
   ret double %l
 }
 
-define double @test80_addrspacecast([100 x double] addrspace(1)* %p, i32 %i) {
+define double @test80_addrspacecast(ptr addrspace(1) %p, i32 %i) {
 ; ALL-LABEL: @test80_addrspacecast(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [100 x double], [100 x double] addrspace(1)* [[P:%.*]], i32 0, i32 [[I:%.*]]
-; ALL-NEXT:    [[L:%.*]] = load double, double addrspace(1)* [[PP1]], align 8
+; ALL-NEXT:    [[T:%.*]] = shl nsw i32 [[I:%.*]], 3
+; ALL-NEXT:    [[Q:%.*]] = addrspacecast ptr addrspace(1) [[P:%.*]] to ptr addrspace(2)
+; ALL-NEXT:    [[TMP1:%.*]] = sext i32 [[T]] to i64
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr addrspace(2) [[Q]], i64 [[TMP1]]
+; ALL-NEXT:    [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(1)
+; ALL-NEXT:    [[L:%.*]] = load double, ptr addrspace(1) [[R]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %t = shl nsw i32 %i, 3
-  %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
-  %pp = getelementptr i8, i8 addrspace(2)* %q, i32 %t
-  %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(1)*
-  %l = load double, double addrspace(1)* %r
+  %q = addrspacecast ptr addrspace(1) %p to ptr addrspace(2)
+  %pp = getelementptr i8, ptr addrspace(2) %q, i32 %t
+  %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(1)
+  %l = load double, ptr addrspace(1) %r
   ret double %l
 }
 
-define double @test80_addrspacecast_2([100 x double] addrspace(1)* %p, i32 %i) {
+define double @test80_addrspacecast_2(ptr addrspace(1) %p, i32 %i) {
 ; ALL-LABEL: @test80_addrspacecast_2(
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [100 x double], [100 x double] addrspace(1)* [[P:%.*]], i32 0, i32 [[I:%.*]]
-; ALL-NEXT:    [[R:%.*]] = addrspacecast double addrspace(1)* [[PP1]] to double addrspace(3)*
-; ALL-NEXT:    [[L:%.*]] = load double, double addrspace(3)* [[R]], align 8
+; ALL-NEXT:    [[T:%.*]] = shl nsw i32 [[I:%.*]], 3
+; ALL-NEXT:    [[Q:%.*]] = addrspacecast ptr addrspace(1) [[P:%.*]] to ptr addrspace(2)
+; ALL-NEXT:    [[TMP1:%.*]] = sext i32 [[T]] to i64
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr addrspace(2) [[Q]], i64 [[TMP1]]
+; ALL-NEXT:    [[R:%.*]] = addrspacecast ptr addrspace(2) [[PP]] to ptr addrspace(3)
+; ALL-NEXT:    [[L:%.*]] = load double, ptr addrspace(3) [[R]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %t = shl nsw i32 %i, 3
-  %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
-  %pp = getelementptr i8, i8 addrspace(2)* %q, i32 %t
-  %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(3)*
-  %l = load double, double addrspace(3)* %r
+  %q = addrspacecast ptr addrspace(1) %p to ptr addrspace(2)
+  %pp = getelementptr i8, ptr addrspace(2) %q, i32 %t
+  %r = addrspacecast ptr addrspace(2) %pp to ptr addrspace(3)
+  %l = load double, ptr addrspace(3) %r
   ret double %l
 }
 
-define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
+define double @test80_as1(ptr addrspace(1) %p, i16 %i) {
 ; ALL-LABEL: @test80_as1(
-; ALL-NEXT:    [[TMP1:%.*]] = sext i16 [[I:%.*]] to i32
-; ALL-NEXT:    [[PP1:%.*]] = getelementptr [100 x double], [100 x double] addrspace(1)* [[P:%.*]], i32 0, i32 [[TMP1]]
-; ALL-NEXT:    [[L:%.*]] = load double, double addrspace(1)* [[PP1]], align 8
+; ALL-NEXT:    [[T:%.*]] = shl nsw i16 [[I:%.*]], 3
+; ALL-NEXT:    [[TMP1:%.*]] = sext i16 [[T]] to i32
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr addrspace(1) [[P:%.*]], i32 [[TMP1]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr addrspace(1) [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %t = shl nsw i16 %i, 3
-  %q = bitcast [100 x double] addrspace(1)* %p to i8 addrspace(1)*
-  %pp = getelementptr i8, i8 addrspace(1)* %q, i16 %t
-  %r = bitcast i8 addrspace(1)* %pp to double addrspace(1)*
-  %l = load double, double addrspace(1)* %r
+  %pp = getelementptr i8, ptr addrspace(1) %p, i16 %t
+  %l = load double, ptr addrspace(1) %pp
   ret double %l
 }
 
-define double @test81(double *%p, float %f) {
+define double @test81(ptr %p, float %f) {
 ; ALL-LABEL: @test81(
 ; ALL-NEXT:    [[I:%.*]] = fptosi float [[F:%.*]] to i64
-; ALL-NEXT:    [[Q:%.*]] = bitcast double* [[P:%.*]] to i8*
-; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, i8* [[Q]], i64 [[I]]
-; ALL-NEXT:    [[R:%.*]] = bitcast i8* [[PP]] to double*
-; ALL-NEXT:    [[L:%.*]] = load double, double* [[R]], align 8
+; ALL-NEXT:    [[PP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[I]]
+; ALL-NEXT:    [[L:%.*]] = load double, ptr [[PP]], align 8
 ; ALL-NEXT:    ret double [[L]]
 ;
   %i = fptosi float %f to i64
-  %q = bitcast double* %p to i8*
-  %pp = getelementptr i8, i8* %q, i64 %i
-  %r = bitcast i8* %pp to double*
-  %l = load double, double* %r
+  %pp = getelementptr i8, ptr %p, i64 %i
+  %l = load double, ptr %pp
   ret double %l
 }
 
@@ -1404,13 +1375,13 @@ define i16 @test88(i16 %v) {
   ret i16 %t
 }
 
-define i32 @PR21388(i32* %v) {
+define i32 @PR21388(ptr %v) {
 ; ALL-LABEL: @PR21388(
-; ALL-NEXT:    [[ICMP:%.*]] = icmp slt i32* [[V:%.*]], null
+; ALL-NEXT:    [[ICMP:%.*]] = icmp slt ptr [[V:%.*]], null
 ; ALL-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
 ; ALL-NEXT:    ret i32 [[SEXT]]
 ;
-  %icmp = icmp slt i32* %v, null
+  %icmp = icmp slt ptr %v, null
   %sext = sext i1 %icmp to i32
   ret i32 %sext
 }

diff  --git a/llvm/test/Transforms/InstCombine/gep-addrspace.ll b/llvm/test/Transforms/InstCombine/gep-addrspace.ll
index a779be88bb06..64813264e976 100644
--- a/llvm/test/Transforms/InstCombine/gep-addrspace.ll
+++ b/llvm/test/Transforms/InstCombine/gep-addrspace.ll
@@ -7,15 +7,14 @@ target triple = "x86_64-pc-win32"
 %myStruct = type { float, [3 x float], [4 x float], i32 }
 
 ; make sure that we are not crashing when creating an illegal type
-define void @func(%myStruct addrspace(1)* nocapture %p) nounwind {
+define void @func(ptr addrspace(1) nocapture %p) nounwind {
 ; CHECK-LABEL: @func(
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr inbounds %myStruct, %myStruct addrspace(1)* %p, i64 0
-  %B = addrspacecast %myStruct addrspace(1)* %A to %myStruct*
-  %C = getelementptr inbounds %myStruct, %myStruct* %B, i32 0, i32 1
-  %D = getelementptr inbounds [3 x float], [3 x float]* %C, i32 0, i32 2
-  %E = load float, float* %D, align 4
+  %B = addrspacecast ptr addrspace(1) %p to ptr
+  %C = getelementptr inbounds %myStruct, ptr %B, i32 0, i32 1
+  %D = getelementptr inbounds [3 x float], ptr %C, i32 0, i32 2
+  %E = load float, ptr %D, align 4
   %F = fsub float %E, undef
   ret void
 }
@@ -23,43 +22,39 @@ define void @func(%myStruct addrspace(1)* nocapture %p) nounwind {
 @array = internal addrspace(3) global [256 x float] zeroinitializer, align 4
 @scalar = internal addrspace(3) global float 0.000000e+00, align 4
 
-define void @keep_necessary_addrspacecast(i64 %i, float** %out0, float** %out1) {
+define void @keep_necessary_addrspacecast(i64 %i, ptr %out0, ptr %out1) {
 ; CHECK-LABEL: @keep_necessary_addrspacecast(
-; CHECK-NEXT:    [[T01:%.*]] = getelementptr [256 x float], [256 x float] addrspace(3)* @array, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT:    [[T0:%.*]] = addrspacecast float addrspace(3)* [[T01]] to float*
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr float, float addrspace(3)* @scalar, i64 [[I]]
-; CHECK-NEXT:    [[T1:%.*]] = addrspacecast float addrspace(3)* [[TMP1]] to float*
-; CHECK-NEXT:    store float* [[T0]], float** [[OUT0:%.*]], align 4
-; CHECK-NEXT:    store float* [[T1]], float** [[OUT1:%.*]], align 4
+; CHECK-NEXT:    [[T0:%.*]] = getelementptr [256 x float], ptr addrspacecast (ptr addrspace(3) @array to ptr), i64 0, i64 [[I:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = getelementptr [0 x float], ptr addrspacecast (ptr addrspace(3) @scalar to ptr), i64 0, i64 [[I]]
+; CHECK-NEXT:    store ptr [[T0]], ptr [[OUT0:%.*]], align 4
+; CHECK-NEXT:    store ptr [[T1]], ptr [[OUT1:%.*]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %t0 = getelementptr [256 x float], [256 x float]* addrspacecast ([256 x float] addrspace(3)* @array to [256 x float]*), i64 0, i64 %i
-  %t1 = getelementptr [0 x float], [0 x float]* addrspacecast (float addrspace(3)* @scalar to [0 x float]*), i64 0, i64 %i
-  store float* %t0, float** %out0, align 4
-  store float* %t1, float** %out1, align 4
+  %t0 = getelementptr [256 x float], ptr addrspacecast (ptr addrspace(3) @array to ptr), i64 0, i64 %i
+  %t1 = getelementptr [0 x float], ptr addrspacecast (ptr addrspace(3) @scalar to ptr), i64 0, i64 %i
+  store ptr %t0, ptr %out0, align 4
+  store ptr %t1, ptr %out1, align 4
   ret void
 }
 
-declare void @escape_alloca(i16*)
+declare void @escape_alloca(ptr)
 
 ; check that addrspacecast is stripped when trying to mark a GEP as inbounds
 define { i8, i8 } @inbounds_after_addrspacecast() {
 ; CHECK-LABEL: @inbounds_after_addrspacecast(
 ; CHECK-NEXT:    [[T0:%.*]] = alloca i16, align 2
-; CHECK-NEXT:    call void @escape_alloca(i16* nonnull [[T0]])
-; CHECK-NEXT:    [[TMPCAST:%.*]] = bitcast i16* [[T0]] to [2 x i8]*
-; CHECK-NEXT:    [[T1:%.*]] = addrspacecast [2 x i8]* [[TMPCAST]] to [2 x i8] addrspace(11)*
-; CHECK-NEXT:    [[T2:%.*]] = getelementptr inbounds [2 x i8], [2 x i8] addrspace(11)* [[T1]], i64 0, i64 1
-; CHECK-NEXT:    [[T3:%.*]] = load i8, i8 addrspace(11)* [[T2]], align 1
+; CHECK-NEXT:    call void @escape_alloca(ptr nonnull [[T0]])
+; CHECK-NEXT:    [[T1:%.*]] = addrspacecast ptr [[T0]] to ptr addrspace(11)
+; CHECK-NEXT:    [[T2:%.*]] = getelementptr inbounds [2 x i8], ptr addrspace(11) [[T1]], i64 0, i64 1
+; CHECK-NEXT:    [[T3:%.*]] = load i8, ptr addrspace(11) [[T2]], align 1
 ; CHECK-NEXT:    [[INSERT:%.*]] = insertvalue { i8, i8 } zeroinitializer, i8 [[T3]], 1
 ; CHECK-NEXT:    ret { i8, i8 } [[INSERT]]
 ;
   %t0 = alloca i16, align 2
-  call void @escape_alloca(i16* %t0)
-  %tmpcast = bitcast i16* %t0 to [2 x i8]*
-  %t1 = addrspacecast [2 x i8]* %tmpcast to [2 x i8] addrspace(11)*
-  %t2 = getelementptr [2 x i8], [2 x i8] addrspace(11)* %t1, i64 0, i64 1
-  %t3 = load i8, i8 addrspace(11)* %t2, align 1
+  call void @escape_alloca(ptr %t0)
+  %t1 = addrspacecast ptr %t0 to ptr addrspace(11)
+  %t2 = getelementptr [2 x i8], ptr addrspace(11) %t1, i64 0, i64 1
+  %t3 = load i8, ptr addrspace(11) %t2, align 1
   %insert = insertvalue { i8, i8 } zeroinitializer, i8 %t3, 1
   ret { i8, i8 } %insert
 }
@@ -68,18 +63,15 @@ define { i8, i8 } @inbounds_after_addrspacecast() {
 declare spir_func <16 x i32> @my_extern_func()
 
 ; check that a bitcast is not generated when we need an addrspace cast
-define void @bitcast_after_gep(<16 x i32>* %t0) {
+define void @bitcast_after_gep(ptr %t0) {
 ; CHECK-LABEL: @bitcast_after_gep(
-; CHECK-NEXT:    [[T4:%.*]] = addrspacecast <16 x i32>* [[T0:%.*]] to <16 x i32> addrspace(3)*
+; CHECK-NEXT:    [[T2:%.*]] = addrspacecast ptr [[T0:%.*]] to ptr addrspace(3)
 ; CHECK-NEXT:    [[CALL:%.*]] = call spir_func <16 x i32> @my_extern_func()
-; CHECK-NEXT:    store <16 x i32> [[CALL]], <16 x i32> addrspace(3)* [[T4]], align 64
+; CHECK-NEXT:    store <16 x i32> [[CALL]], ptr addrspace(3) [[T2]], align 64
 ; CHECK-NEXT:    ret void
 ;
-  %t1 = bitcast <16 x i32>* %t0 to [16 x i32]*
-  %t2 = addrspacecast [16 x i32]* %t1 to [16 x i32] addrspace(3)*
-  %t3 = getelementptr inbounds [16 x i32], [16 x i32] addrspace(3)* %t2, i64 0, i64 0
-  %t4 = bitcast i32 addrspace(3)* %t3 to <16 x i32> addrspace(3)*
+  %t2 = addrspacecast ptr %t0 to ptr addrspace(3)
   %call = call spir_func <16 x i32> @my_extern_func()
-  store <16 x i32> %call, <16 x i32> addrspace(3)* %t4
+  store <16 x i32> %call, ptr addrspace(3) %t2
   ret void
 }

diff  --git a/llvm/test/Transforms/InstCombine/gep-custom-dl.ll b/llvm/test/Transforms/InstCombine/gep-custom-dl.ll
index 8eedad9bea57..e80f1b242a52 100644
--- a/llvm/test/Transforms/InstCombine/gep-custom-dl.ll
+++ b/llvm/test/Transforms/InstCombine/gep-custom-dl.ll
@@ -11,157 +11,155 @@ target datalayout = "e-m:m-p:40:64:64:32-i32:32-i16:16-i8:8-n32"
 @Global = external global [10 x i8]
 
 ; Test that two array indexing geps fold
-define i32* @test1(i32* %I) {
+define ptr @test1(ptr %I) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[I:%.*]], i32 21
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i32 21
+; CHECK-NEXT:    ret ptr [[B]]
 ;
-  %A = getelementptr i32, i32* %I, i8 17
-  %B = getelementptr i32, i32* %A, i16 4
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i8 17
+  %B = getelementptr i32, ptr %A, i16 4
+  ret ptr %B
 }
 
 ; Test that two getelementptr insts fold
-define i32* @test2({ i32 }* %I) {
+define ptr @test2(ptr %I) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr { i32 }, { i32 }* [[I:%.*]], i32 1, i32 0
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr { i32 }, ptr [[I:%.*]], i32 1
+; CHECK-NEXT:    ret ptr [[A]]
 ;
-  %A = getelementptr { i32 }, { i32 }* %I, i32 1
-  %B = getelementptr { i32 }, { i32 }* %A, i32 0, i32 0
-  ret i32* %B
+  %A = getelementptr { i32 }, ptr %I, i32 1
+  ret ptr %A
 }
 
 define void @test3(i8 %B) {
 ; This should be turned into a constexpr instead of being an instruction
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT:    store i8 [[B:%.*]], i8* getelementptr inbounds ([10 x i8], [10 x i8]* @Global, i32 0, i32 4), align 1
+; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds ([10 x i8], ptr @Global, i32 0, i32 4), align 1
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr [10 x i8], [10 x i8]* @Global, i32 0, i32 4
-  store i8 %B, i8* %A
+  %A = getelementptr [10 x i8], ptr @Global, i32 0, i32 4
+  store i8 %B, ptr %A
   ret void
 }
 
-%as1_ptr_struct = type { i32 addrspace(1)* }
-%as2_ptr_struct = type { i32 addrspace(2)* }
+%as1_ptr_struct = type { ptr addrspace(1) }
+%as2_ptr_struct = type { ptr addrspace(2) }
 
 @global_as2 = addrspace(2) global i32 zeroinitializer
- at global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { i32 addrspace(2)* @global_as2 }
+ at global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { ptr addrspace(2) @global_as2 }
 
 ; This should be turned into a constexpr instead of being an instruction
-define void @test_evaluate_gep_nested_as_ptrs(i32 addrspace(2)* %B) {
+define void @test_evaluate_gep_nested_as_ptrs(ptr addrspace(2) %B) {
 ; CHECK-LABEL: @test_evaluate_gep_nested_as_ptrs(
-; CHECK-NEXT:    store i32 addrspace(2)* [[B:%.*]], i32 addrspace(2)* addrspace(1)* getelementptr inbounds ([[AS2_PTR_STRUCT:%.*]], [[AS2_PTR_STRUCT]] addrspace(1)* @global_as1_as2_ptr, i32 0, i32 0), align 8
+; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) @global_as1_as2_ptr, align 8
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr %as2_ptr_struct, %as2_ptr_struct addrspace(1)* @global_as1_as2_ptr, i32 0, i32 0
-  store i32 addrspace(2)* %B, i32 addrspace(2)* addrspace(1)* %A
+  store ptr addrspace(2) %B, ptr addrspace(1) @global_as1_as2_ptr
   ret void
 }
 
- at arst = addrspace(1) global [4 x i8 addrspace(2)*] zeroinitializer
+ at arst = addrspace(1) global [4 x ptr addrspace(2)] zeroinitializer
 
-define void @test_evaluate_gep_as_ptrs_array(i8 addrspace(2)* %B) {
+define void @test_evaluate_gep_as_ptrs_array(ptr addrspace(2) %B) {
 ; CHECK-LABEL: @test_evaluate_gep_as_ptrs_array(
-; CHECK-NEXT:    store i8 addrspace(2)* [[B:%.*]], i8 addrspace(2)* addrspace(1)* getelementptr inbounds ([4 x i8 addrspace(2)*], [4 x i8 addrspace(2)*] addrspace(1)* @arst, i32 0, i32 2), align 16
+; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) getelementptr inbounds ([4 x ptr addrspace(2)], ptr addrspace(1) @arst, i32 0, i32 2), align 16
 ; CHECK-NEXT:    ret void
 ;
 
-  %A = getelementptr [4 x i8 addrspace(2)*], [4 x i8 addrspace(2)*] addrspace(1)* @arst, i16 0, i16 2
-  store i8 addrspace(2)* %B, i8 addrspace(2)* addrspace(1)* %A
+  %A = getelementptr [4 x ptr addrspace(2)], ptr addrspace(1) @arst, i16 0, i16 2
+  store ptr addrspace(2) %B, ptr addrspace(1) %A
   ret void
 }
 
-define i32* @test4(i32* %I, i32 %C, i32 %D) {
+define ptr @test4(ptr %I, i32 %C, i32 %D) {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, i32* [[I:%.*]], i32 [[C:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[A]], i32 [[D:%.*]]
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i32 [[C:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[A]], i32 [[D:%.*]]
+; CHECK-NEXT:    ret ptr [[B]]
 ;
-  %A = getelementptr i32, i32* %I, i32 %C
-  %B = getelementptr i32, i32* %A, i32 %D
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i32 %C
+  %B = getelementptr i32, ptr %A, i32 %D
+  ret ptr %B
 }
 
 
-define i1 @test5({ i32, i32 }* %x, { i32, i32 }* %y) {
+define i1 @test5(ptr %x, ptr %y) {
 ; CHECK-LABEL: @test5(
-; CHECK-NEXT:    [[TMP_4:%.*]] = icmp eq { i32, i32 }* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP_4:%.*]] = icmp eq ptr [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[TMP_4]]
 ;
-  %tmp.1 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 1
-  %tmp.3 = getelementptr { i32, i32 }, { i32, i32 }* %y, i32 0, i32 1
+  %tmp.1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1
+  %tmp.3 = getelementptr { i32, i32 }, ptr %y, i32 0, i32 1
   ;; seteq x, y
-  %tmp.4 = icmp eq i32* %tmp.1, %tmp.3
+  %tmp.4 = icmp eq ptr %tmp.1, %tmp.3
   ret i1 %tmp.4
 }
 
 %S = type { i32, [ 100 x i32] }
 
-define <2 x i1> @test6(<2 x i32> %X, <2 x %S*> %P) nounwind {
+define <2 x i1> @test6(<2 x i32> %X, <2 x ptr> %P) nounwind {
 ; CHECK-LABEL: @test6(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S*> %P, <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i32> %X
-  %B = getelementptr inbounds %S, <2 x %S*> %P, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 0, i32 0>
-  %C = icmp eq <2 x i32*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i32> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i32> %X
+  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 0, i32 0>
+  %C = icmp eq <2 x ptr> %A, %B
   ret <2 x i1> %C
 }
 
 ; Same as above, but indices scalarized.
-define <2 x i1> @test6b(<2 x i32> %X, <2 x %S*> %P) nounwind {
+define <2 x i1> @test6b(<2 x i32> %X, <2 x ptr> %P) nounwind {
 ; CHECK-LABEL: @test6b(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S*> %P, i32 0, i32 1, <2 x i32> %X
-  %B = getelementptr inbounds %S, <2 x %S*> %P, i32 0, i32 0
-  %C = icmp eq <2 x i32*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr> %P, i32 0, i32 1, <2 x i32> %X
+  %B = getelementptr inbounds %S, <2 x ptr> %P, i32 0, i32 0
+  %C = icmp eq <2 x ptr> %A, %B
   ret <2 x i1> %C
 }
 
 @G = external global [3 x i8]
-define i8* @test7(i16 %Idx) {
+define ptr @test7(i16 %Idx) {
 ; CHECK-LABEL: @test7(
 ; CHECK-NEXT:    [[ZE_IDX:%.*]] = zext i16 [[IDX:%.*]] to i32
-; CHECK-NEXT:    [[TMP:%.*]] = getelementptr [3 x i8], [3 x i8]* @G, i32 0, i32 [[ZE_IDX]]
-; CHECK-NEXT:    ret i8* [[TMP]]
+; CHECK-NEXT:    [[TMP:%.*]] = getelementptr i8, ptr @G, i32 [[ZE_IDX]]
+; CHECK-NEXT:    ret ptr [[TMP]]
 ;
   %ZE_Idx = zext i16 %Idx to i32
-  %tmp = getelementptr i8, i8* getelementptr ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i32 %ZE_Idx
-  ret i8* %tmp
+  %tmp = getelementptr i8, ptr @G, i32 %ZE_Idx
+  ret ptr %tmp
 }
 
 
 ; Test folding of constantexpr geps into normal geps.
 @Array = external global [40 x i32]
-define i32 *@test8(i32 %X) {
+define ptr @test8(i32 %X) {
 ; CHECK-LABEL: @test8(
-; CHECK-NEXT:    [[A:%.*]] = getelementptr [40 x i32], [40 x i32]* @Array, i32 0, i32 [[X:%.*]]
-; CHECK-NEXT:    ret i32* [[A]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr @Array, i32 [[X:%.*]]
+; CHECK-NEXT:    ret ptr [[A]]
 ;
-  %A = getelementptr i32, i32* getelementptr ([40 x i32], [40 x i32]* @Array, i32 0, i32 0), i32 %X
-  ret i32* %A
+  %A = getelementptr i32, ptr @Array, i32 %X
+  ret ptr %A
 }
 
-define i32 *@test9(i32 *%base, i8 %ind) {
+define ptr @test9(ptr %base, i8 %ind) {
 ; CHECK-LABEL: @test9(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[IND:%.*]] to i32
-; CHECK-NEXT:    [[RES:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i32 [[TMP1]]
-; CHECK-NEXT:    ret i32* [[RES]]
+; CHECK-NEXT:    [[RES:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i32 [[TMP1]]
+; CHECK-NEXT:    ret ptr [[RES]]
 ;
-  %res = getelementptr i32, i32 *%base, i8 %ind
-  ret i32* %res
+  %res = getelementptr i32, ptr %base, i8 %ind
+  ret ptr %res
 }
 
 define i32 @test10() {
 ; CHECK-LABEL: @test10(
 ; CHECK-NEXT:    ret i32 8
 ;
-  %A = getelementptr { i32, double }, { i32, double }* null, i32 0, i32 1
-  %B = ptrtoint double* %A to i32
+  %A = getelementptr { i32, double }, ptr null, i32 0, i32 1
+  %B = ptrtoint ptr %A to i32
   ret i32 %B
 }
 
@@ -170,17 +168,16 @@ define i32 @test10() {
 define i16 @constant_fold_custom_dl() {
 ; CHECK-LABEL: @constant_fold_custom_dl(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i16 ptrtoint (i8 addrspace(1)* getelementptr (i8, i8 addrspace(1)* getelementptr inbounds ([1000 x i8], [1000 x i8] addrspace(1)* @X_as1, i32 1, i32 0), i32 sext (i16 sub (i16 0, i16 ptrtoint ([1000 x i8] addrspace(1)* @X_as1 to i16)) to i32)) to i16)
+; CHECK-NEXT:    ret i16 ptrtoint (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) getelementptr inbounds ([1000 x i8], ptr addrspace(1) @X_as1, i32 1, i32 0), i32 sext (i16 sub (i16 0, i16 ptrtoint (ptr addrspace(1) @X_as1 to i16)) to i32)) to i16)
 ;
 
 entry:
-  %A = bitcast i8 addrspace(1)* getelementptr inbounds ([1000 x i8], [1000 x i8] addrspace(1)* @X_as1, i64 1, i64 0) to i8 addrspace(1)*
-  %B = bitcast i8 addrspace(1)* getelementptr inbounds ([1000 x i8], [1000 x i8] addrspace(1)* @X_as1, i64 0, i64 0) to i8 addrspace(1)*
+  %A = bitcast ptr addrspace(1) getelementptr inbounds ([1000 x i8], ptr addrspace(1) @X_as1, i64 1, i64 0) to ptr addrspace(1)
 
-  %B2 = ptrtoint i8 addrspace(1)* %B to i16
+  %B2 = ptrtoint ptr addrspace(1) @X_as1 to i16
   %C = sub i16 0, %B2
-  %D = getelementptr i8, i8 addrspace(1)* %A, i16 %C
-  %E = ptrtoint i8 addrspace(1)* %D to i16
+  %D = getelementptr i8, ptr addrspace(1) %A, i16 %C
+  %E = ptrtoint ptr addrspace(1) %D to i16
 
   ret i16 %E
 }

diff  --git a/llvm/test/Transforms/InstCombine/gep-vector.ll b/llvm/test/Transforms/InstCombine/gep-vector.ll
index d242032d3dd4..9ebb245325b1 100644
--- a/llvm/test/Transforms/InstCombine/gep-vector.ll
+++ b/llvm/test/Transforms/InstCombine/gep-vector.ll
@@ -3,155 +3,142 @@
 
 @block = global [64 x [8192 x i8]] zeroinitializer, align 1
 
-define <2 x i8*> @vectorindex1() {
+define <2 x ptr> @vectorindex1() {
 ; CHECK-LABEL: @vectorindex1(
-; CHECK-NEXT:    ret <2 x i8*> getelementptr inbounds ([64 x [8192 x i8]], [64 x [8192 x i8]]* @block, <2 x i64> zeroinitializer, <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer)
+; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer)
 ;
-  %1 = getelementptr inbounds [64 x [8192 x i8]], [64 x [8192 x i8]]* @block, i64 0, <2 x i64> <i64 0, i64 1>, i64 8192
-  ret <2 x i8*> %1
+  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, <2 x i64> <i64 0, i64 1>, i64 8192
+  ret <2 x ptr> %1
 }
 
-define <2 x i8*> @vectorindex2() {
+define <2 x ptr> @vectorindex2() {
 ; CHECK-LABEL: @vectorindex2(
-; CHECK-NEXT:    ret <2 x i8*> getelementptr inbounds ([64 x [8192 x i8]], [64 x [8192 x i8]]* @block, <2 x i64> zeroinitializer, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8191, i64 1>)
+; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8191, i64 1>)
 ;
-  %1 = getelementptr inbounds [64 x [8192 x i8]], [64 x [8192 x i8]]* @block, i64 0, i64 1, <2 x i64> <i64 8191, i64 8193>
-  ret <2 x i8*> %1
+  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, i64 1, <2 x i64> <i64 8191, i64 8193>
+  ret <2 x ptr> %1
 }
 
-define <2 x i8*> @vectorindex3() {
+define <2 x ptr> @vectorindex3() {
 ; CHECK-LABEL: @vectorindex3(
-; CHECK-NEXT:    ret <2 x i8*> getelementptr inbounds ([64 x [8192 x i8]], [64 x [8192 x i8]]* @block, <2 x i64> zeroinitializer, <2 x i64> <i64 0, i64 2>, <2 x i64> <i64 8191, i64 1>)
+; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> <i64 0, i64 2>, <2 x i64> <i64 8191, i64 1>)
 ;
-  %1 = getelementptr inbounds [64 x [8192 x i8]], [64 x [8192 x i8]]* @block, i64 0, <2 x i64> <i64 0, i64 1>, <2 x i64> <i64 8191, i64 8193>
-  ret <2 x i8*> %1
+  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, <2 x i64> <i64 0, i64 1>, <2 x i64> <i64 8191, i64 8193>
+  ret <2 x ptr> %1
 }
 
 ; Negative test - datalayout's alloc size for the 2 types must match.
 
-define i32* @bitcast_vec_to_array_gep(<7 x i32>* %x, i64 %y, i64 %z) {
+define ptr @bitcast_vec_to_array_gep(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_vec_to_array_gep(
-; CHECK-NEXT:    [[ARR_PTR:%.*]] = bitcast <7 x i32>* [[X:%.*]] to [7 x i32]*
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], [7 x i32]* [[ARR_PTR]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %arr_ptr = bitcast <7 x i32>* %x to [7 x i32]*
-  %gep = getelementptr [7 x i32], [7 x i32]* %arr_ptr, i64 %y, i64 %z
-  ret i32* %gep
+  %gep = getelementptr [7 x i32], ptr %x, i64 %y, i64 %z
+  ret ptr %gep
 }
 
 ; Negative test - datalayout's alloc size for the 2 types must match.
 
-define i32* @bitcast_array_to_vec_gep([3 x i32]* %x, i64 %y, i64 %z) {
+define ptr @bitcast_array_to_vec_gep(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_array_to_vec_gep(
-; CHECK-NEXT:    [[VEC_PTR:%.*]] = bitcast [3 x i32]* [[X:%.*]] to <3 x i32>*
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <3 x i32>, <3 x i32>* [[VEC_PTR]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <3 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %vec_ptr = bitcast [3 x i32]* %x to <3 x i32>*
-  %gep = getelementptr inbounds <3 x i32>, <3 x i32>* %vec_ptr, i64 %y, i64 %z
-  ret i32* %gep
+  %gep = getelementptr inbounds <3 x i32>, ptr %x, i64 %y, i64 %z
+  ret ptr %gep
 }
 
 ; Sizes and types match - safe to remove bitcast.
 
-define i32* @bitcast_vec_to_array_gep_matching_alloc_size(<4 x i32>* %x, i64 %y, i64 %z) {
+define ptr @bitcast_vec_to_array_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_vec_to_array_gep_matching_alloc_size(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <4 x i32>, <4 x i32>* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %arr_ptr = bitcast <4 x i32>* %x to [4 x i32]*
-  %gep = getelementptr [4 x i32], [4 x i32]* %arr_ptr, i64 %y, i64 %z
-  ret i32* %gep
+  %gep = getelementptr [4 x i32], ptr %x, i64 %y, i64 %z
+  ret ptr %gep
 }
 
 ; Sizes and types match - safe to remove bitcast.
 
-define i32* @bitcast_array_to_vec_gep_matching_alloc_size([4 x i32]* %x, i64 %y, i64 %z) {
+define ptr @bitcast_array_to_vec_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_array_to_vec_gep_matching_alloc_size(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <4 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %vec_ptr = bitcast [4 x i32]* %x to <4 x i32>*
-  %gep = getelementptr inbounds <4 x i32>, <4 x i32>* %vec_ptr, i64 %y, i64 %z
-  ret i32* %gep
+  %gep = getelementptr inbounds <4 x i32>, ptr %x, i64 %y, i64 %z
+  ret ptr %gep
 }
 
 ; Negative test - datalayout's alloc size for the 2 types must match.
 
-define i32 addrspace(3)* @bitcast_vec_to_array_addrspace(<7 x i32>* %x, i64 %y, i64 %z) {
+define ptr addrspace(3) @bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_vec_to_array_addrspace(
-; CHECK-NEXT:    [[ARR_PTR:%.*]] = bitcast <7 x i32>* [[X:%.*]] to [7 x i32]*
-; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast [7 x i32]* [[ARR_PTR]] to [7 x i32] addrspace(3)*
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], [7 x i32] addrspace(3)* [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32 addrspace(3)* [[GEP]]
+; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
 ;
-  %arr_ptr = bitcast <7 x i32>* %x to [7 x i32]*
-  %asc = addrspacecast [7 x i32]* %arr_ptr to [7 x i32] addrspace(3)*
-  %gep = getelementptr [7 x i32], [7 x i32] addrspace(3)* %asc, i64 %y, i64 %z
-  ret i32 addrspace(3)* %gep
+  %asc = addrspacecast ptr %x to ptr addrspace(3)
+  %gep = getelementptr [7 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
+  ret ptr addrspace(3) %gep
 }
 
 ; Negative test - datalayout's alloc size for the 2 types must match.
 
-define i32 addrspace(3)* @inbounds_bitcast_vec_to_array_addrspace(<7 x i32>* %x, i64 %y, i64 %z) {
+define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace(
-; CHECK-NEXT:    [[ARR_PTR:%.*]] = bitcast <7 x i32>* [[X:%.*]] to [7 x i32]*
-; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast [7 x i32]* [[ARR_PTR]] to [7 x i32] addrspace(3)*
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32] addrspace(3)* [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    ret i32 addrspace(3)* [[GEP]]
+; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
 ;
-  %arr_ptr = bitcast <7 x i32>* %x to [7 x i32]*
-  %asc = addrspacecast [7 x i32]* %arr_ptr to [7 x i32] addrspace(3)*
-  %gep = getelementptr inbounds [7 x i32], [7 x i32] addrspace(3)* %asc, i64 %y, i64 %z
-  ret i32 addrspace(3)* %gep
+  %asc = addrspacecast ptr %x to ptr addrspace(3)
+  %gep = getelementptr inbounds [7 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
+  ret ptr addrspace(3) %gep
 }
 
 ; Sizes and types match - safe to remove bitcast.
 
-define i32 addrspace(3)* @bitcast_vec_to_array_addrspace_matching_alloc_size(<4 x i32>* %x, i64 %y, i64 %z) {
+define ptr addrspace(3) @bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @bitcast_vec_to_array_addrspace_matching_alloc_size(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <4 x i32>, <4 x i32>* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = addrspacecast i32* [[GEP]] to i32 addrspace(3)*
-; CHECK-NEXT:    ret i32 addrspace(3)* [[TMP1]]
+; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
 ;
-  %arr_ptr = bitcast <4 x i32>* %x to [4 x i32]*
-  %asc = addrspacecast [4 x i32]* %arr_ptr to [4 x i32] addrspace(3)*
-  %gep = getelementptr [4 x i32], [4 x i32] addrspace(3)* %asc, i64 %y, i64 %z
-  ret i32 addrspace(3)* %gep
+  %asc = addrspacecast ptr %x to ptr addrspace(3)
+  %gep = getelementptr [4 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
+  ret ptr addrspace(3) %gep
 }
 
 ; Sizes and types match - safe to remove bitcast.
 
-define i32 addrspace(3)* @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(<4 x i32>* %x, i64 %y, i64 %z) {
+define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <4 x i32>, <4 x i32>* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = addrspacecast i32* [[GEP]] to i32 addrspace(3)*
-; CHECK-NEXT:    ret i32 addrspace(3)* [[TMP1]]
+; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
 ;
-  %arr_ptr = bitcast <4 x i32>* %x to [4 x i32]*
-  %asc = addrspacecast [4 x i32]* %arr_ptr to [4 x i32] addrspace(3)*
-  %gep = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* %asc, i64 %y, i64 %z
-  ret i32 addrspace(3)* %gep
+  %asc = addrspacecast ptr %x to ptr addrspace(3)
+  %gep = getelementptr inbounds [4 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
+  ret ptr addrspace(3) %gep
 }
 
-; Negative test - avoid doing bitcast on i8*, because '16' should be scaled by 'vscale'.
+; Negative test - avoid doing bitcast on ptr, because '16' should be scaled by 'vscale'.
 
-define i8* @test_accumulate_constant_offset_vscale_nonzero(<vscale x 16 x i1> %pg, i8* %base) {
-; CHECK-LABEL: @test_accumulate_constant_offset_vscale_nonzero
-; CHECK-NEXT:   %bc = bitcast i8* %base to <vscale x 16 x i8>*
-; CHECK-NEXT:   %gep = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %bc, i64 1, i64 4
-; CHECK-NEXT:   ret i8* %gep
-  %bc = bitcast i8* %base to <vscale x 16 x i8>*
-  %gep = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %bc, i64 1, i64 4
-  ret i8* %gep
+define ptr @test_accumulate_constant_offset_vscale_nonzero(<vscale x 16 x i1> %pg, ptr %base) {
+; CHECK-LABEL: @test_accumulate_constant_offset_vscale_nonzero(
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 16 x i8>, ptr [[BASE:%.*]], i64 1, i64 4
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr <vscale x 16 x i8>, ptr %base, i64 1, i64 4
+  ret ptr %gep
 }
 
-define i8* @test_accumulate_constant_offset_vscale_zero(<vscale x 16 x i1> %pg, i8* %base) {
-; CHECK-LABEL: @test_accumulate_constant_offset_vscale_zero
-; CHECK-NEXT:   %[[RES:.*]] = getelementptr i8, i8* %base, i64 4
-; CHECK-NEXT:   ret i8* %[[RES]]
-  %bc = bitcast i8* %base to <vscale x 16 x i8>*
-  %gep = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %bc, i64 0, i64 4
-  ret i8* %gep
+define ptr @test_accumulate_constant_offset_vscale_zero(<vscale x 16 x i1> %pg, ptr %base) {
+; CHECK-LABEL: @test_accumulate_constant_offset_vscale_zero(
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <vscale x 16 x i8>, ptr [[BASE:%.*]], i64 0, i64 4
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr <vscale x 16 x i8>, ptr %base, i64 0, i64 4
+  ret ptr %gep
 }

diff  --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll
index 943abc36bf46..0f8c70f8d458 100644
--- a/llvm/test/Transforms/InstCombine/getelementptr.ll
+++ b/llvm/test/Transforms/InstCombine/getelementptr.ll
@@ -14,220 +14,210 @@ target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"
 @Global_as1 = external addrspace(1) global [10 x i8]
 
 ; Test noop elimination
-define i32* @test1(i32* %I) {
+define ptr @test1(ptr %I) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    ret i32* [[I:%.*]]
+; CHECK-NEXT:    ret ptr [[I:%.*]]
 ;
-  %A = getelementptr i32, i32* %I, i64 0
-  ret i32* %A
+  ret ptr %I
 }
 
-define i32 addrspace(1)* @test1_as1(i32 addrspace(1)* %I) {
+define ptr addrspace(1) @test1_as1(ptr addrspace(1) %I) {
 ; CHECK-LABEL: @test1_as1(
-; CHECK-NEXT:    ret i32 addrspace(1)* [[I:%.*]]
+; CHECK-NEXT:    ret ptr addrspace(1) [[I:%.*]]
 ;
-  %A = getelementptr i32, i32 addrspace(1)* %I, i64 0
-  ret i32 addrspace(1)* %A
+  ret ptr addrspace(1) %I
 }
 
 ; Test noop elimination
-define i32* @test2(i32* %I) {
+define ptr @test2(ptr %I) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    ret i32* [[I:%.*]]
+; CHECK-NEXT:    ret ptr [[I:%.*]]
 ;
-  %A = getelementptr i32, i32* %I
-  ret i32* %A
+  %A = getelementptr i32, ptr %I
+  ret ptr %A
 }
 
 ; Test that two array indexing geps fold
-define i32* @test3(i32* %I) {
+define ptr @test3(ptr %I) {
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 21
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 21
+; CHECK-NEXT:    ret ptr [[B]]
 ;
-  %A = getelementptr i32, i32* %I, i64 17
-  %B = getelementptr i32, i32* %A, i64 4
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i64 17
+  %B = getelementptr i32, ptr %A, i64 4
+  ret ptr %B
 }
 
 ; Test that two getelementptr insts fold
-define i32* @test4({ i32 }* %I) {
+define ptr @test4(ptr %I) {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr { i32 }, { i32 }* [[I:%.*]], i64 1, i32 0
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr { i32 }, ptr [[I:%.*]], i64 1
+; CHECK-NEXT:    ret ptr [[A]]
 ;
-  %A = getelementptr { i32 }, { i32 }* %I, i64 1
-  %B = getelementptr { i32 }, { i32 }* %A, i64 0, i32 0
-  ret i32* %B
+  %A = getelementptr { i32 }, ptr %I, i64 1
+  ret ptr %A
 }
 
 define void @test5(i8 %B) {
         ; This should be turned into a constexpr instead of being an instruction
 ; CHECK-LABEL: @test5(
-; CHECK-NEXT:    store i8 [[B:%.*]], i8* getelementptr inbounds ([10 x i8], [10 x i8]* @Global, i64 0, i64 4), align 1
+; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds ([10 x i8], ptr @Global, i64 0, i64 4), align 1
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr [10 x i8], [10 x i8]* @Global, i64 0, i64 4
-  store i8 %B, i8* %A
+  %A = getelementptr [10 x i8], ptr @Global, i64 0, i64 4
+  store i8 %B, ptr %A
   ret void
 }
 
 define void @test5_as1(i8 %B) {
         ; This should be turned into a constexpr instead of being an instruction
 ; CHECK-LABEL: @test5_as1(
-; CHECK-NEXT:    store i8 [[B:%.*]], i8 addrspace(1)* getelementptr inbounds ([10 x i8], [10 x i8] addrspace(1)* @Global_as1, i16 0, i16 4), align 1
+; CHECK-NEXT:    store i8 [[B:%.*]], ptr addrspace(1) getelementptr inbounds ([10 x i8], ptr addrspace(1) @Global_as1, i16 0, i16 4), align 1
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr [10 x i8], [10 x i8] addrspace(1)* @Global_as1, i16 0, i16 4
-  store i8 %B, i8 addrspace(1)* %A
+  %A = getelementptr [10 x i8], ptr addrspace(1) @Global_as1, i16 0, i16 4
+  store i8 %B, ptr addrspace(1) %A
   ret void
 }
 
-%as1_ptr_struct = type { i32 addrspace(1)* }
-%as2_ptr_struct = type { i32 addrspace(2)* }
+%as1_ptr_struct = type { ptr addrspace(1) }
+%as2_ptr_struct = type { ptr addrspace(2) }
 
 @global_as2 = addrspace(2) global i32 zeroinitializer
- at global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { i32 addrspace(2)* @global_as2 }
+ at global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { ptr addrspace(2) @global_as2 }
 
 ; This should be turned into a constexpr instead of being an instruction
-define void @test_evaluate_gep_nested_as_ptrs(i32 addrspace(2)* %B) {
+define void @test_evaluate_gep_nested_as_ptrs(ptr addrspace(2) %B) {
 ; CHECK-LABEL: @test_evaluate_gep_nested_as_ptrs(
-; CHECK-NEXT:    store i32 addrspace(2)* [[B:%.*]], i32 addrspace(2)* addrspace(1)* getelementptr inbounds ([[AS2_PTR_STRUCT:%.*]], [[AS2_PTR_STRUCT]] addrspace(1)* @global_as1_as2_ptr, i16 0, i32 0), align 8
+; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) @global_as1_as2_ptr, align 8
 ; CHECK-NEXT:    ret void
 ;
-  %A = getelementptr %as2_ptr_struct, %as2_ptr_struct addrspace(1)* @global_as1_as2_ptr, i16 0, i32 0
-  store i32 addrspace(2)* %B, i32 addrspace(2)* addrspace(1)* %A
+  store ptr addrspace(2) %B, ptr addrspace(1) @global_as1_as2_ptr
   ret void
 }
 
- at arst = addrspace(1) global [4 x i8 addrspace(2)*] zeroinitializer
+ at arst = addrspace(1) global [4 x ptr addrspace(2)] zeroinitializer
 
-define void @test_evaluate_gep_as_ptrs_array(i8 addrspace(2)* %B) {
+define void @test_evaluate_gep_as_ptrs_array(ptr addrspace(2) %B) {
 ; CHECK-LABEL: @test_evaluate_gep_as_ptrs_array(
-; CHECK-NEXT:    store i8 addrspace(2)* [[B:%.*]], i8 addrspace(2)* addrspace(1)* getelementptr inbounds ([4 x i8 addrspace(2)*], [4 x i8 addrspace(2)*] addrspace(1)* @arst, i16 0, i16 2), align 4
+; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) getelementptr inbounds ([4 x ptr addrspace(2)], ptr addrspace(1) @arst, i16 0, i16 2), align 4
 ; CHECK-NEXT:    ret void
 ;
 
-  %A = getelementptr [4 x i8 addrspace(2)*], [4 x i8 addrspace(2)*] addrspace(1)* @arst, i16 0, i16 2
-  store i8 addrspace(2)* %B, i8 addrspace(2)* addrspace(1)* %A
+  %A = getelementptr [4 x ptr addrspace(2)], ptr addrspace(1) @arst, i16 0, i16 2
+  store ptr addrspace(2) %B, ptr addrspace(1) %A
   ret void
 }
 
-define i32* @test7(i32* %I, i64 %C, i64 %D) {
+define ptr @test7(ptr %I, i64 %C, i64 %D) {
 ; CHECK-LABEL: @test7(
-; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 [[C:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[A]], i64 [[D:%.*]]
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[C:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[A]], i64 [[D:%.*]]
+; CHECK-NEXT:    ret ptr [[B]]
 ;
-  %A = getelementptr i32, i32* %I, i64 %C
-  %B = getelementptr i32, i32* %A, i64 %D
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i64 %C
+  %B = getelementptr i32, ptr %A, i64 %D
+  ret ptr %B
 }
 
-define i8* @test8([10 x i32]* %X) {
+define ptr @test8(ptr %X) {
         ;; Fold into the cast.
 ; CHECK-LABEL: @test8(
-; CHECK-NEXT:    [[B:%.*]] = bitcast [10 x i32]* [[X:%.*]] to i8*
-; CHECK-NEXT:    ret i8* [[B]]
+; CHECK-NEXT:    ret ptr [[X:%.*]]
 ;
-  %A = getelementptr [10 x i32], [10 x i32]* %X, i64 0, i64 0
-  %B = bitcast i32* %A to i8*
-  ret i8* %B
+  ret ptr %X
 }
 
 define i32 @test9() {
 ; CHECK-LABEL: @test9(
 ; CHECK-NEXT:    ret i32 8
 ;
-  %A = getelementptr { i32, double }, { i32, double }* null, i32 0, i32 1
-  %B = ptrtoint double* %A to i32
+  %A = getelementptr { i32, double }, ptr null, i32 0, i32 1
+  %B = ptrtoint ptr %A to i32
   ret i32 %B
 }
 
-define i1 @test10({ i32, i32 }* %x, { i32, i32 }* %y) {
+define i1 @test10(ptr %x, ptr %y) {
 ; CHECK-LABEL: @test10(
-; CHECK-NEXT:    [[T4:%.*]] = icmp eq { i32, i32 }* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[T4]]
 ;
-  %t1 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 1
-  %t3 = getelementptr { i32, i32 }, { i32, i32 }* %y, i32 0, i32 1
-  %t4 = icmp eq i32* %t1, %t3
+  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1
+  %t3 = getelementptr { i32, i32 }, ptr %y, i32 0, i32 1
+  %t4 = icmp eq ptr %t1, %t3
   ret i1 %t4
 }
 
-define i1 @test10_addrspacecast({ i32, i32 }* %x, { i32, i32 } addrspace(3)* %y) {
+define i1 @test10_addrspacecast(ptr %x, ptr addrspace(3) %y) {
 ; CHECK-LABEL: @test10_addrspacecast(
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[X:%.*]], i64 0, i32 1
-; CHECK-NEXT:    [[T3:%.*]] = getelementptr { i32, i32 }, { i32, i32 } addrspace(3)* [[Y:%.*]], i64 0, i32 1
-; CHECK-NEXT:    [[T3_C:%.*]] = addrspacecast i32 addrspace(3)* [[T3]] to i32*
-; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32* [[T1]], [[T3_C]]
+; CHECK-NEXT:    [[T1:%.*]] = getelementptr { i32, i32 }, ptr [[X:%.*]], i64 0, i32 1
+; CHECK-NEXT:    [[T3:%.*]] = getelementptr { i32, i32 }, ptr addrspace(3) [[Y:%.*]], i64 0, i32 1
+; CHECK-NEXT:    [[T3_C:%.*]] = addrspacecast ptr addrspace(3) [[T3]] to ptr
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[T1]], [[T3_C]]
 ; CHECK-NEXT:    ret i1 [[T4]]
 ;
-  %t1 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 1
-  %t3 = getelementptr { i32, i32 }, { i32, i32 } addrspace(3)* %y, i32 0, i32 1
-  %t3.c = addrspacecast i32 addrspace(3)* %t3 to i32*
-  %t4 = icmp eq i32* %t1, %t3.c
+  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1
+  %t3 = getelementptr { i32, i32 }, ptr addrspace(3) %y, i32 0, i32 1
+  %t3.c = addrspacecast ptr addrspace(3) %t3 to ptr
+  %t4 = icmp eq ptr %t1, %t3.c
   ret i1 %t4
 }
 
-define i1 @test11({ i32, i32 }* %X) {
+define i1 @test11(ptr %X) {
 ; CHECK-LABEL: @test11(
-; CHECK-NEXT:    [[Q:%.*]] = icmp eq { i32, i32 }* [[X:%.*]], null
+; CHECK-NEXT:    [[Q:%.*]] = icmp eq ptr [[X:%.*]], null
 ; CHECK-NEXT:    ret i1 [[Q]]
 ;
-  %P = getelementptr { i32, i32 }, { i32, i32 }* %X, i32 0, i32 0
-  %Q = icmp eq i32* %P, null
+  %P = getelementptr { i32, i32 }, ptr %X, i32 0, i32 0
+  %Q = icmp eq ptr %P, null
   ret i1 %Q
 }
 
 
 ; PR4748
-define i32 @test12(%struct.A* %a) {
+define i32 @test12(ptr %a) {
 ; CHECK-LABEL: @test12(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[G3:%.*]] = getelementptr [[STRUCT_A:%.*]], %struct.A* [[A:%.*]], i64 0, i32 1
-; CHECK-NEXT:    store i32 10, i32* [[G3]], align 4
+; CHECK-NEXT:    [[G3:%.*]] = getelementptr [[STRUCT_A:%.*]], ptr [[A:%.*]], i64 0, i32 1
+; CHECK-NEXT:    store i32 10, ptr [[G3]], align 4
 ; CHECK-NEXT:    ret i32 10
 ;
 entry:
-  %g3 = getelementptr %struct.A, %struct.A* %a, i32 0, i32 1
-  store i32 10, i32* %g3, align 4
+  %g3 = getelementptr %struct.A, ptr %a, i32 0, i32 1
+  store i32 10, ptr %g3, align 4
 
-  %g4 = getelementptr %struct.A, %struct.A* %a, i32 0, i32 0
 
-  %new_a = bitcast %struct.B* %g4 to %struct.A*
 
-  %g5 = getelementptr %struct.A, %struct.A* %new_a, i32 0, i32 1
-  %a_a = load i32, i32* %g5, align 4
+  %g5 = getelementptr %struct.A, ptr %a, i32 0, i32 1
+  %a_a = load i32, ptr %g5, align 4
   ret i32 %a_a
 }
 
 
 ; PR2235
 %S = type { i32, [ 100 x i32] }
-define i1 @test13(i64 %X, %S* %P) {
+define i1 @test13(i64 %X, ptr %P) {
 ; CHECK-LABEL: @test13(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %A = getelementptr inbounds %S, %S* %P, i32 0, i32 1, i64 %X
-  %B = getelementptr inbounds %S, %S* %P, i32 0, i32 0
-  %C = icmp eq i32* %A, %B
+  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i64 %X
+  %C = icmp eq ptr %A, %P
   ret i1 %C
 }
 
-define <2 x i1> @test13_vector(<2 x i64> %X, <2 x %S*> %P) nounwind {
+define <2 x i1> @test13_vector(<2 x i64> %X, <2 x ptr> %P) nounwind {
 ; CHECK-LABEL: @test13_vector(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 -1, i64 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i64> %X
-  %B = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
-  %C = icmp eq <2 x i32*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i64> %X
+  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
+  %C = icmp eq <2 x ptr> %A, %B
   ret <2 x i1> %C
 }
 
-define <2 x i1> @test13_vector2(i64 %X, <2 x %S*> %P) nounwind {
+define <2 x i1> @test13_vector2(i64 %X, <2 x ptr> %P) nounwind {
 ; CHECK-LABEL: @test13_vector2(
 ; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
@@ -235,14 +225,14 @@ define <2 x i1> @test13_vector2(i64 %X, <2 x %S*> %P) nounwind {
 ; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
-  %B = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
-  %C = icmp eq <2 x i32*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
+  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
+  %C = icmp eq <2 x ptr> %A, %B
   ret <2 x i1> %C
 }
 
 ; This is a test of icmp + shl nuw in disguise - 4611... is 0x3fff...
-define <2 x i1> @test13_vector3(i64 %X, <2 x %S*> %P) nounwind {
+define <2 x i1> @test13_vector3(i64 %X, <2 x ptr> %P) nounwind {
 ; CHECK-LABEL: @test13_vector3(
 ; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
@@ -250,218 +240,214 @@ define <2 x i1> @test13_vector3(i64 %X, <2 x %S*> %P) nounwind {
 ; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
-  %B = getelementptr inbounds %S, <2 x %S*> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 1, i32 1>, i64 1
-  %C = icmp eq <2 x i32*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
+  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 1, i32 1>, i64 1
+  %C = icmp eq <2 x ptr> %A, %B
   ret <2 x i1> %C
 }
 
-define i1 @test13_as1(i16 %X, %S addrspace(1)* %P) {
+define i1 @test13_as1(i16 %X, ptr addrspace(1) %P) {
 ; CHECK-LABEL: @test13_as1(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %A = getelementptr inbounds %S, %S addrspace(1)* %P, i16 0, i32 1, i16 %X
-  %B = getelementptr inbounds %S, %S addrspace(1)* %P, i16 0, i32 0
-  %C = icmp eq i32 addrspace(1)* %A, %B
+  %A = getelementptr inbounds %S, ptr addrspace(1) %P, i16 0, i32 1, i16 %X
+  %C = icmp eq ptr addrspace(1) %A, %P
   ret i1 %C
 }
 
-define <2 x i1> @test13_vector_as1(<2 x i16> %X, <2 x %S addrspace(1)*> %P) {
+define <2 x i1> @test13_vector_as1(<2 x i16> %X, <2 x ptr addrspace(1)> %P) {
 ; CHECK-LABEL: @test13_vector_as1(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i16> [[X:%.*]], <i16 -1, i16 -1>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
-  %A = getelementptr inbounds %S, <2 x %S addrspace(1)*> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 1, i32 1>, <2 x i16> %X
-  %B = getelementptr inbounds %S, <2 x %S addrspace(1)*> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 0, i32 0>
-  %C = icmp eq <2 x i32 addrspace(1)*> %A, %B
+  %A = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 1, i32 1>, <2 x i16> %X
+  %B = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 0, i32 0>
+  %C = icmp eq <2 x ptr addrspace(1)> %A, %B
   ret <2 x i1> %C
 }
 
-define i1 @test13_i32(i32 %X, %S* %P) {
+define i1 @test13_i32(i32 %X, ptr %P) {
 ; CHECK-LABEL: @test13_i32(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %A = getelementptr inbounds %S, %S* %P, i32 0, i32 1, i32 %X
-  %B = getelementptr inbounds %S, %S* %P, i32 0, i32 0
-  %C = icmp eq i32* %A, %B
+  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i32 %X
+  %C = icmp eq ptr %A, %P
   ret i1 %C
 }
 
-define i1 @test13_i16(i16 %X, %S* %P) {
+define i1 @test13_i16(i16 %X, ptr %P) {
 ; CHECK-LABEL: @test13_i16(
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %A = getelementptr inbounds %S, %S* %P, i16 0, i32 1, i16 %X
-  %B = getelementptr inbounds %S, %S* %P, i16 0, i32 0
-  %C = icmp eq i32* %A, %B
+  %A = getelementptr inbounds %S, ptr %P, i16 0, i32 1, i16 %X
+  %C = icmp eq ptr %A, %P
   ret i1 %C
 }
 
-define i1 @test13_i128(i128 %X, %S* %P) {
+define i1 @test13_i128(i128 %X, ptr %P) {
 ; CHECK-LABEL: @test13_i128(
 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[TMP1]], -1
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %A = getelementptr inbounds %S, %S* %P, i128 0, i32 1, i128 %X
-  %B = getelementptr inbounds %S, %S* %P, i128 0, i32 0
-  %C = icmp eq i32* %A, %B
+  %A = getelementptr inbounds %S, ptr %P, i128 0, i32 1, i128 %X
+  %C = icmp eq ptr %A, %P
   ret i1 %C
 }
 
 
 @G = external global [3 x i8]
-define i8* @test14(i32 %idx) {
+define ptr @test14(i32 %idx) {
 ; CHECK-LABEL: @test14(
 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[IDX:%.*]] to i64
-; CHECK-NEXT:    [[T:%.*]] = getelementptr [3 x i8], [3 x i8]* @G, i64 0, i64 [[ZEXT]]
-; CHECK-NEXT:    ret i8* [[T]]
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr @G, i64 [[ZEXT]]
+; CHECK-NEXT:    ret ptr [[T]]
 ;
   %zext = zext i32 %idx to i64
-  %t = getelementptr i8, i8* getelementptr ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i64 %zext
-  ret i8* %t
+  %t = getelementptr i8, ptr @G, i64 %zext
+  ret ptr %t
 }
 
 
 ; Test folding of constantexpr geps into normal geps.
 @Array = external global [40 x i32]
-define i32 *@test15(i64 %X) {
+define ptr @test15(i64 %X) {
 ; CHECK-LABEL: @test15(
-; CHECK-NEXT:    [[A:%.*]] = getelementptr [40 x i32], [40 x i32]* @Array, i64 0, i64 [[X:%.*]]
-; CHECK-NEXT:    ret i32* [[A]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr @Array, i64 [[X:%.*]]
+; CHECK-NEXT:    ret ptr [[A]]
 ;
-  %A = getelementptr i32, i32* getelementptr ([40 x i32], [40 x i32]* @Array, i64 0, i64 0), i64 %X
-  ret i32* %A
+  %A = getelementptr i32, ptr @Array, i64 %X
+  ret ptr %A
 }
 
 
-define i32* @test16(i32* %X, i32 %Idx) {
+define ptr @test16(ptr %X, i32 %Idx) {
 ; CHECK-LABEL: @test16(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
-; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, i32* [[X:%.*]], i64 [[TMP1]]
-; CHECK-NEXT:    ret i32* [[R]]
+; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[X:%.*]], i64 [[TMP1]]
+; CHECK-NEXT:    ret ptr [[R]]
 ;
-  %R = getelementptr i32, i32* %X, i32 %Idx
-  ret i32* %R
+  %R = getelementptr i32, ptr %X, i32 %Idx
+  ret ptr %R
 }
 
 
-define i1 @test17(i16* %P, i32 %I, i32 %J) {
+define i1 @test17(ptr %P, i32 %I, i32 %J) {
 ; CHECK-LABEL: @test17(
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], [[J:%.*]]
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16* %P, i32 %I
-  %Y = getelementptr inbounds i16, i16* %P, i32 %J
-  %C = icmp ult i16* %X, %Y
+  %X = getelementptr inbounds i16, ptr %P, i32 %I
+  %Y = getelementptr inbounds i16, ptr %P, i32 %J
+  %C = icmp ult ptr %X, %Y
   ret i1 %C
 }
 
-define i1 @test18(i16* %P, i32 %I) {
+define i1 @test18(ptr %P, i32 %I) {
 ; CHECK-LABEL: @test18(
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16* %P, i32 %I
-  %C = icmp ult i16* %X, %P
+  %X = getelementptr inbounds i16, ptr %P, i32 %I
+  %C = icmp ult ptr %X, %P
   ret i1 %C
 }
 
 ; Larger than the pointer size for a non-zero address space
-define i1 @test18_as1(i16 addrspace(1)* %P, i32 %I) {
+define i1 @test18_as1(ptr addrspace(1) %P, i32 %I) {
 ; CHECK-LABEL: @test18_as1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16 addrspace(1)* %P, i32 %I
-  %C = icmp ult i16 addrspace(1)* %X, %P
+  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I
+  %C = icmp ult ptr addrspace(1) %X, %P
   ret i1 %C
 }
 
 ; Smaller than the pointer size for a non-zero address space
-define i1 @test18_as1_i32(i16 addrspace(1)* %P, i32 %I) {
+define i1 @test18_as1_i32(ptr addrspace(1) %P, i32 %I) {
 ; CHECK-LABEL: @test18_as1_i32(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16 addrspace(1)* %P, i32 %I
-  %C = icmp ult i16 addrspace(1)* %X, %P
+  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I
+  %C = icmp ult ptr addrspace(1) %X, %P
   ret i1 %C
 }
 
 ; Smaller than pointer size
-define i1 @test18_i16(i16* %P, i16 %I) {
+define i1 @test18_i16(ptr %P, i16 %I) {
 ; CHECK-LABEL: @test18_i16(
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[I:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16* %P, i16 %I
-  %C = icmp ult i16* %X, %P
+  %X = getelementptr inbounds i16, ptr %P, i16 %I
+  %C = icmp ult ptr %X, %P
   ret i1 %C
 }
 
 ; Same as pointer size
-define i1 @test18_i64(i16* %P, i64 %I) {
+define i1 @test18_i64(ptr %P, i64 %I) {
 ; CHECK-LABEL: @test18_i64(
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[I:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16* %P, i64 %I
-  %C = icmp ult i16* %X, %P
+  %X = getelementptr inbounds i16, ptr %P, i64 %I
+  %C = icmp ult ptr %X, %P
   ret i1 %C
 }
 
 ; Larger than the pointer size
-define i1 @test18_i128(i16* %P, i128 %I) {
+define i1 @test18_i128(ptr %P, i128 %I) {
 ; CHECK-LABEL: @test18_i128(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[I:%.*]], 9223372036854775808
 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i128 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
-  %X = getelementptr inbounds i16, i16* %P, i128 %I
-  %C = icmp ult i16* %X, %P
+  %X = getelementptr inbounds i16, ptr %P, i128 %I
+  %C = icmp ult ptr %X, %P
   ret i1 %C
 }
 
-define i32 @test19(i32* %P, i32 %A, i32 %B) {
+define i32 @test19(ptr %P, i32 %A, i32 %B) {
 ; CHECK-LABEL: @test19(
 ; CHECK-NEXT:    [[T10:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[T11:%.*]] = zext i1 [[T10]] to i32
 ; CHECK-NEXT:    ret i32 [[T11]]
 ;
-  %t4 = getelementptr inbounds i32, i32* %P, i32 %A
-  %t9 = getelementptr inbounds i32, i32* %P, i32 %B
-  %t10 = icmp eq i32* %t4, %t9
+  %t4 = getelementptr inbounds i32, ptr %P, i32 %A
+  %t9 = getelementptr inbounds i32, ptr %P, i32 %B
+  %t10 = icmp eq ptr %t4, %t9
   %t11 = zext i1 %t10 to i32
   ret i32 %t11
 }
 
-define i32 @test20(i32* %P, i32 %A, i32 %B) {
+define i32 @test20(ptr %P, i32 %A, i32 %B) {
 ; CHECK-LABEL: @test20(
 ; CHECK-NEXT:    [[T6:%.*]] = icmp eq i32 [[A:%.*]], 0
 ; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32
 ; CHECK-NEXT:    ret i32 [[T7]]
 ;
-  %t4 = getelementptr inbounds i32, i32* %P, i32 %A
-  %t6 = icmp eq i32* %t4, %P
+  %t4 = getelementptr inbounds i32, ptr %P, i32 %A
+  %t6 = icmp eq ptr %t4, %P
   %t7 = zext i1 %t6 to i32
   ret i32 %t7
 }
 
-define i32 @test20_as1(i32 addrspace(1)* %P, i32 %A, i32 %B) {
+define i32 @test20_as1(ptr addrspace(1) %P, i32 %A, i32 %B) {
 ; CHECK-LABEL: @test20_as1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[A:%.*]] to i16
 ; CHECK-NEXT:    [[T6:%.*]] = icmp eq i16 [[TMP1]], 0
 ; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32
 ; CHECK-NEXT:    ret i32 [[T7]]
 ;
-  %t4 = getelementptr inbounds i32, i32 addrspace(1)* %P, i32 %A
-  %t6 = icmp eq i32 addrspace(1)* %t4, %P
+  %t4 = getelementptr inbounds i32, ptr addrspace(1) %P, i32 %A
+  %t6 = icmp eq ptr addrspace(1) %t4, %P
   %t7 = zext i1 %t6 to i32
   ret i32 %t7
 }
@@ -470,27 +456,25 @@ define i32 @test20_as1(i32 addrspace(1)* %P, i32 %A, i32 %B) {
 define i32 @test21() {
 ; CHECK-LABEL: @test21(
 ; CHECK-NEXT:    [[PBOB1:%.*]] = alloca [[INTSTRUCT:%.*]], align 8
-; CHECK-NEXT:    [[PBOBEL:%.*]] = getelementptr inbounds [[INTSTRUCT]], %intstruct* [[PBOB1]], i64 0, i32 0
-; CHECK-NEXT:    [[RVAL:%.*]] = load i32, i32* [[PBOBEL]], align 8
+; CHECK-NEXT:    [[RVAL:%.*]] = load i32, ptr [[PBOB1]], align 8
 ; CHECK-NEXT:    ret i32 [[RVAL]]
 ;
   %pbob1 = alloca %intstruct
-  %pbob2 = getelementptr %intstruct, %intstruct* %pbob1
-  %pbobel = getelementptr %intstruct, %intstruct* %pbob2, i64 0, i32 0
-  %rval = load i32, i32* %pbobel
+  %pbob2 = getelementptr %intstruct, ptr %pbob1
+  %rval = load i32, ptr %pbob2
   ret i32 %rval
 }
 
 
- at A = global i32 1               ; <i32*> [#uses=1]
- at B = global i32 2               ; <i32*> [#uses=1]
+ at A = global i32 1               ; <ptr> [#uses=1]
+ at B = global i32 2               ; <ptr> [#uses=1]
 
 define i1 @test22() {
 ; CHECK-LABEL: @test22(
-; CHECK-NEXT:    ret i1 icmp ult (i32* getelementptr inbounds (i32, i32* @A, i64 1), i32* getelementptr (i32, i32* @B, i64 2))
+; CHECK-NEXT:    ret i1 icmp ult (ptr getelementptr inbounds (i32, ptr @A, i64 1), ptr getelementptr (i32, ptr @B, i64 2))
 ;
-  %C = icmp ult i32* getelementptr (i32, i32* @A, i64 1),
-  getelementptr (i32, i32* @B, i64 2)
+  %C = icmp ult ptr getelementptr (i32, ptr @A, i64 1),
+  getelementptr (i32, ptr @B, i64 2)
   ret i1 %C
 }
 
@@ -501,22 +485,22 @@ define i1 @test23() {
 ; CHECK-LABEL: @test23(
 ; CHECK-NEXT:    ret i1 false
 ;
-  %A = getelementptr %X, %X* null, i64 0, i32 0, i64 0                ; <i32*> [#uses=1]
-  %B = icmp ne i32* %A, null              ; <i1> [#uses=1]
+  %A = getelementptr %X, ptr null, i64 0, i32 0, i64 0                ; <ptr> [#uses=1]
+  %B = icmp ne ptr %A, null              ; <i1> [#uses=1]
   ret i1 %B
 }
 
 define void @test25() {
 ; CHECK-LABEL: @test25(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    store i64 poison, i64* null, align 4294967296
+; CHECK-NEXT:    store i64 poison, ptr null, align 4294967296
 ; CHECK-NEXT:    tail call void @foo25(i32 0, i64 poison)
 ; CHECK-NEXT:    unreachable
 ;
 entry:
-  %t = getelementptr { i64, i64, i64, i64 }, { i64, i64, i64, i64 }* null, i32 0, i32 3
-  %t.upgrd.1 = load i64, i64* %t
-  %t8.ui = load i64, i64* null
+  %t = getelementptr { i64, i64, i64, i64 }, ptr null, i32 0, i32 3
+  %t.upgrd.1 = load i64, ptr %t
+  %t8.ui = load i64, ptr null
   %t8 = bitcast i64 %t8.ui to i64
   %t9 = and i64 %t8, %t.upgrd.1
   %sext = trunc i64 %t9 to i32
@@ -529,44 +513,40 @@ declare void @foo25(i32, i64)
 
 
 ; PR1637
-define i1 @test26(i8* %arr) {
+define i1 @test26(ptr %arr) {
 ; CHECK-LABEL: @test26(
 ; CHECK-NEXT:    ret i1 true
 ;
-  %X = getelementptr i8, i8* %arr, i32 1
-  %Y = getelementptr i8, i8* %arr, i32 1
-  %test = icmp uge i8* %X, %Y
+  %X = getelementptr i8, ptr %arr, i32 1
+  %Y = getelementptr i8, ptr %arr, i32 1
+  %test = icmp uge ptr %X, %Y
   ret i1 %test
 }
 
   %struct.__large_struct = type { [100 x i64] }
   %struct.compat_siginfo = type { i32, i32, i32, { [29 x i32] } }
   %struct.siginfo_t = type { i32, i32, i32, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] } }
-  %struct.sigval_t = type { i8* }
+  %struct.sigval_t = type { ptr }
 
-define i32 @test27(%struct.compat_siginfo* %to, %struct.siginfo_t* %from) {
+define i32 @test27(ptr %to, ptr %from) {
 ; CHECK-LABEL: @test27(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[FROM_ADDR:%.*]] = alloca %struct.siginfo_t*, align 8
-; CHECK-NEXT:    [[T344:%.*]] = load %struct.siginfo_t*, %struct.siginfo_t** [[FROM_ADDR]], align 8
-; CHECK-NEXT:    [[T349:%.*]] = getelementptr [[STRUCT_SIGINFO_T:%.*]], %struct.siginfo_t* [[T344]], i64 0, i32 3, i32 0, i32 3, i32 0
-; CHECK-NEXT:    [[T349350:%.*]] = bitcast i8** [[T349]] to i32*
-; CHECK-NEXT:    [[T351:%.*]] = load i32, i32* [[T349350]], align 8
-; CHECK-NEXT:    [[T360:%.*]] = call i32 asm sideeffect "...", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"(i32 [[T351]], %struct.__large_struct* elementtype([[STRUCT___LARGE_STRUCT:%.*]]) null, i32 -14, i32 0) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT:    [[FROM_ADDR:%.*]] = alloca ptr, align 8
+; CHECK-NEXT:    [[T344:%.*]] = load ptr, ptr [[FROM_ADDR]], align 8
+; CHECK-NEXT:    [[T348:%.*]] = getelementptr [[STRUCT_SIGINFO_T:%.*]], ptr [[T344]], i64 0, i32 3, i32 0, i32 3
+; CHECK-NEXT:    [[T351:%.*]] = load i32, ptr [[T348]], align 8
+; CHECK-NEXT:    [[T360:%.*]] = call i32 asm sideeffect "...", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"(i32 [[T351]], ptr elementtype([[STRUCT___LARGE_STRUCT:%.*]]) null, i32 -14, i32 0) #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    unreachable
 ;
 entry:
-  %from_addr = alloca %struct.siginfo_t*
-  %t344 = load %struct.siginfo_t*, %struct.siginfo_t** %from_addr, align 8
-  %t345 = getelementptr %struct.siginfo_t, %struct.siginfo_t* %t344, i32 0, i32 3
-  %t346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }* %t345, i32 0, i32 0
-  %t346347 = bitcast { i32, i32, [0 x i8], %struct.sigval_t, i32 }* %t346 to { i32, i32, %struct.sigval_t }*
-  %t348 = getelementptr { i32, i32, %struct.sigval_t }, { i32, i32, %struct.sigval_t }* %t346347, i32 0, i32 2
-  %t349 = getelementptr %struct.sigval_t, %struct.sigval_t* %t348, i32 0, i32 0
-  %t349350 = bitcast i8** %t349 to i32*
-  %t351 = load i32, i32* %t349350, align 8
+  %from_addr = alloca ptr
+  %t344 = load ptr, ptr %from_addr, align 8
+  %t345 = getelementptr %struct.siginfo_t, ptr %t344, i32 0, i32 3
+  %t346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }, ptr %t345, i32 0, i32 0
+  %t348 = getelementptr { i32, i32, %struct.sigval_t }, ptr %t346, i32 0, i32 2
+  %t351 = load i32, ptr %t348, align 8
   %t360 = call i32 asm sideeffect "...",
-  "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %t351, %struct.__large_struct* elementtype(%struct.__large_struct) null, i32 -14, i32 0 )
+  "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %t351, ptr elementtype(%struct.__large_struct) null, i32 -14, i32 0 )
   unreachable
 }
 
@@ -579,14 +559,14 @@ define i32 @test28() nounwind  {
 ; CHECK-LABEL: @test28(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[ORIENTATIONS:%.*]] = alloca [1 x [1 x %struct.x]], align 8
-; CHECK-NEXT:    [[T3:%.*]] = call i32 @puts(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0)) #[[ATTR0]]
+; CHECK-NEXT:    [[T3:%.*]] = call i32 @puts(ptr noundef nonnull dereferenceable(1) @.str) #[[ATTR0]]
 ; CHECK-NEXT:    br label [[BB10:%.*]]
 ; CHECK:       bb10:
 ; CHECK-NEXT:    [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[BB10]] ]
 ; CHECK-NEXT:    [[T12_REC:%.*]] = xor i32 [[INDVAR]], -1
 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[T12_REC]] to i64
-; CHECK-NEXT:    [[T12:%.*]] = getelementptr inbounds [1 x [1 x %struct.x]], [1 x [1 x %struct.x]]* [[ORIENTATIONS]], i64 1, i64 0, i64 [[TMP0]]
-; CHECK-NEXT:    [[T16:%.*]] = call i32 (i8*, ...) @printf(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str1, i64 0, i64 0), %struct.x* nonnull [[T12]]) #[[ATTR0]]
+; CHECK-NEXT:    [[T12:%.*]] = getelementptr inbounds [1 x [1 x %struct.x]], ptr [[ORIENTATIONS]], i64 1, i64 0, i64 [[TMP0]]
+; CHECK-NEXT:    [[T16:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str1, ptr nonnull [[T12]]) #[[ATTR0]]
 ; CHECK-NEXT:    [[T84:%.*]] = icmp eq i32 [[INDVAR]], 0
 ; CHECK-NEXT:    [[INDVAR_NEXT]] = add i32 [[INDVAR]], 1
 ; CHECK-NEXT:    br i1 [[T84]], label [[BB17:%.*]], label [[BB10]]
@@ -595,18 +575,17 @@ define i32 @test28() nounwind  {
 ;
 entry:
   %orientations = alloca [1 x [1 x %struct.x]]
-  %t3 = call i32 @puts( i8* getelementptr ([6 x i8], [6 x i8]* @.str, i32 0, i32 0) ) nounwind
-  %t45 = getelementptr inbounds [1 x [1 x %struct.x]], [1 x [1 x %struct.x]]* %orientations, i32 1, i32 0, i32 0
-  %orientations62 = getelementptr [1 x [1 x %struct.x]], [1 x [1 x %struct.x]]* %orientations, i32 0, i32 0, i32 0
+  %t3 = call i32 @puts( ptr @.str ) nounwind
+  %t45 = getelementptr inbounds [1 x [1 x %struct.x]], ptr %orientations, i32 1, i32 0, i32 0
   br label %bb10
 
 bb10:
   %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb10 ]
   %t.0.reg2mem.0.rec = mul i32 %indvar, -1
   %t12.rec = add i32 %t.0.reg2mem.0.rec, -1
-  %t12 = getelementptr inbounds %struct.x, %struct.x* %t45, i32 %t12.rec
-  %t16 = call i32 (i8*, ...) @printf( i8* nonnull dereferenceable(1) getelementptr ([12 x i8], [12 x i8]* @.str1, i32 0, i32 0), %struct.x* %t12 ) nounwind
-  %t84 = icmp eq %struct.x* %t12, %orientations62
+  %t12 = getelementptr inbounds %struct.x, ptr %t45, i32 %t12.rec
+  %t16 = call i32 (ptr, ...) @printf( ptr nonnull dereferenceable(1) @.str1, ptr %t12 ) nounwind
+  %t84 = icmp eq ptr %t12, %orientations
   %indvar.next = add i32 %indvar, 1
   br i1 %t84, label %bb17, label %bb10
 
@@ -614,19 +593,19 @@ bb17:
   ret i32 0
 }
 
-declare i32 @puts(i8*)
+declare i32 @puts(ptr)
 
-declare i32 @printf(i8*, ...)
+declare i32 @printf(ptr, ...)
 
 
 
 
 ; rdar://6762290
   %T = type <{ i64, i64, i64 }>
-define i32 @test29(i8* %start, i32 %X) nounwind {
+define i32 @test29(ptr %start, i32 %X) nounwind {
 ; CHECK-LABEL: @test29(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    store i64 poison, i64* null, align 4294967296
+; CHECK-NEXT:    store i64 poison, ptr null, align 4294967296
 ; CHECK-NEXT:    br i1 poison, label [[IF_THEN216:%.*]], label [[IF_END363:%.*]]
 ; CHECK:       if.then216:
 ; CHECK-NEXT:    ret i32 1
@@ -634,13 +613,12 @@ define i32 @test29(i8* %start, i32 %X) nounwind {
 ; CHECK-NEXT:    ret i32 0
 ;
 entry:
-  %t3 = load i64, i64* null
-  %add.ptr = getelementptr i8, i8* %start, i64 %t3
-  %t158 = load i32, i32* null
-  %add.ptr159 = getelementptr %T, %T* null, i32 %t158
-  %add.ptr209 = getelementptr i8, i8* %start, i64 0
-  %add.ptr212 = getelementptr i8, i8* %add.ptr209, i32 %X
-  %cmp214 = icmp ugt i8* %add.ptr212, %add.ptr
+  %t3 = load i64, ptr null
+  %add.ptr = getelementptr i8, ptr %start, i64 %t3
+  %t158 = load i32, ptr null
+  %add.ptr159 = getelementptr %T, ptr null, i32 %t158
+  %add.ptr212 = getelementptr i8, ptr %start, i32 %X
+  %cmp214 = icmp ugt ptr %add.ptr212, %add.ptr
   br i1 %cmp214, label %if.then216, label %if.end363
 
 if.then216:
@@ -657,135 +635,124 @@ define i32 @test30(i32 %m, i32 %n) nounwind {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N:%.*]] to i64
 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca i32, i64 [[TMP0]], align 4
-; CHECK-NEXT:    call void @test30f(i32* nonnull [[TMP1]]) #[[ATTR0]]
+; CHECK-NEXT:    call void @test30f(ptr nonnull [[TMP1]]) #[[ATTR0]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[M:%.*]] to i64
-; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i32, i32* [[TMP1]], i64 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4
+; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [0 x i32], ptr [[TMP1]], i64 0, i64 [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
 ; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
 entry:
   %0 = alloca i32, i32 %n, align 4
-  %1 = bitcast i32* %0 to [0 x i32]*
-  call void @test30f(i32* %0) nounwind
-  %2 = getelementptr [0 x i32], [0 x i32]* %1, i32 0, i32 %m
-  %3 = load i32, i32* %2, align 4
-  ret i32 %3
+  call void @test30f(ptr %0) nounwind
+  %1 = getelementptr [0 x i32], ptr %0, i32 0, i32 %m
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
 }
 
-declare void @test30f(i32*)
+declare void @test30f(ptr)
 
 
 
-define i1 @test31(i32* %A) {
+define i1 @test31(ptr %A) {
 ; CHECK-LABEL: @test31(
 ; CHECK-NEXT:    ret i1 true
 ;
-  %B = getelementptr i32, i32* %A, i32 1
-  %C = getelementptr i32, i32* %A, i64 1
-  %V = icmp eq i32* %B, %C
+  %B = getelementptr i32, ptr %A, i32 1
+  %C = getelementptr i32, ptr %A, i64 1
+  %V = icmp eq ptr %B, %C
   ret i1 %V
 }
 
 
 ; PR1345
-define i8* @test32(i8* %v) {
+define ptr @test32(ptr %v) {
 ; CHECK-LABEL: @test32(
-; CHECK-NEXT:    [[A:%.*]] = alloca [4 x i8*], align 16
-; CHECK-NEXT:    [[B:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[A]], i64 0, i64 0
-; CHECK-NEXT:    store i8* null, i8** [[B]], align 16
-; CHECK-NEXT:    [[D:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[A]], i64 0, i64 1
-; CHECK-NEXT:    store i8* [[V:%.*]], i8** [[D]], align 8
-; CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[A]], i64 0, i64 2
-; CHECK-NEXT:    [[G:%.*]] = load i8*, i8** [[F]], align 16
-; CHECK-NEXT:    ret i8* [[G]]
-;
-  %A = alloca [4 x i8*], align 16
-  %B = getelementptr [4 x i8*], [4 x i8*]* %A, i32 0, i32 0
-  store i8* null, i8** %B
-  %C = bitcast [4 x i8*]* %A to { [16 x i8] }*
-  %D = getelementptr { [16 x i8] }, { [16 x i8] }* %C, i32 0, i32 0, i32 8
-  %E = bitcast i8* %D to i8**
-  store i8* %v, i8** %E
-  %F = getelementptr [4 x i8*], [4 x i8*]* %A, i32 0, i32 2
-  %G = load i8*, i8** %F
-  ret i8* %G
+; CHECK-NEXT:    [[A:%.*]] = alloca [4 x ptr], align 16
+; CHECK-NEXT:    store ptr null, ptr [[A]], align 16
+; CHECK-NEXT:    [[D:%.*]] = getelementptr inbounds { [16 x i8] }, ptr [[A]], i64 0, i32 0, i64 8
+; CHECK-NEXT:    store ptr [[V:%.*]], ptr [[D]], align 8
+; CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [4 x ptr], ptr [[A]], i64 0, i64 2
+; CHECK-NEXT:    [[G:%.*]] = load ptr, ptr [[F]], align 16
+; CHECK-NEXT:    ret ptr [[G]]
+;
+  %A = alloca [4 x ptr], align 16
+  store ptr null, ptr %A
+  %D = getelementptr { [16 x i8] }, ptr %A, i32 0, i32 0, i32 8
+  store ptr %v, ptr %D
+  %F = getelementptr [4 x ptr], ptr %A, i32 0, i32 2
+  %G = load ptr, ptr %F
+  ret ptr %G
 }
 
 ; PR3290
 %struct.Key = type { { i32, i32 } }
 %struct.anon = type <{ i8, [3 x i8], i32 }>
 
-define i32* @test33(%struct.Key* %A) {
+define ptr @test33(ptr %A) {
 ; CHECK-LABEL: @test33(
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[STRUCT_KEY:%.*]], %struct.Key* [[A:%.*]], i64 0, i32 0, i32 1
-; CHECK-NEXT:    ret i32* [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [[STRUCT_ANON:%.*]], ptr [[A:%.*]], i64 0, i32 2
+; CHECK-NEXT:    ret ptr [[C]]
 ;
-  %B = bitcast %struct.Key* %A to %struct.anon*
-  %C = getelementptr %struct.anon, %struct.anon* %B, i32 0, i32 2
-  ret i32* %C
+  %C = getelementptr %struct.anon, ptr %A, i32 0, i32 2
+  ret ptr %C
 }
 
-define i32 addrspace(1)* @test33_as1(%struct.Key addrspace(1)* %A) {
+define ptr addrspace(1) @test33_as1(ptr addrspace(1) %A) {
 ; CHECK-LABEL: @test33_as1(
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[STRUCT_KEY:%.*]], [[STRUCT_KEY]] addrspace(1)* [[A:%.*]], i16 0, i32 0, i32 1
-; CHECK-NEXT:    ret i32 addrspace(1)* [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [[STRUCT_ANON:%.*]], ptr addrspace(1) [[A:%.*]], i16 0, i32 2
+; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
 ;
-  %B = bitcast %struct.Key addrspace(1)* %A to %struct.anon addrspace(1)*
-  %C = getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i32 0, i32 2
-  ret i32 addrspace(1)* %C
+  %C = getelementptr %struct.anon, ptr addrspace(1) %A, i32 0, i32 2
+  ret ptr addrspace(1) %C
 }
 
-define i32 addrspace(1)* @test33_array_as1([10 x i32] addrspace(1)* %A) {
+define ptr addrspace(1) @test33_array_as1(ptr addrspace(1) %A) {
 ; CHECK-LABEL: @test33_array_as1(
-; CHECK-NEXT:    [[C:%.*]] = getelementptr [10 x i32], [10 x i32] addrspace(1)* [[A:%.*]], i16 0, i16 2
-; CHECK-NEXT:    ret i32 addrspace(1)* [[C]]
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [5 x i32], ptr addrspace(1) [[A:%.*]], i16 0, i16 2
+; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
 ;
-  %B = bitcast [10 x i32] addrspace(1)* %A to [5 x i32] addrspace(1)*
-  %C = getelementptr [5 x i32], [5 x i32] addrspace(1)* %B, i32 0, i32 2
-  ret i32 addrspace(1)* %C
+  %C = getelementptr [5 x i32], ptr addrspace(1) %A, i32 0, i32 2
+  ret ptr addrspace(1) %C
 }
 
 ; Make sure the GEP indices use the right pointer sized integer
-define i32 addrspace(1)* @test33_array_struct_as1([10 x %struct.Key] addrspace(1)* %A) {
+define ptr addrspace(1) @test33_array_struct_as1(ptr addrspace(1) %A) {
 ; CHECK-LABEL: @test33_array_struct_as1(
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [10 x %struct.Key], [10 x %struct.Key] addrspace(1)* [[A:%.*]], i16 0, i16 1, i32 0, i32 0
-; CHECK-NEXT:    ret i32 addrspace(1)* [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [20 x i32], ptr addrspace(1) [[A:%.*]], i16 0, i16 2
+; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
 ;
-  %B = bitcast [10 x %struct.Key] addrspace(1)* %A to [20 x i32] addrspace(1)*
-  %C = getelementptr [20 x i32], [20 x i32] addrspace(1)* %B, i32 0, i32 2
-  ret i32 addrspace(1)* %C
+  %C = getelementptr [20 x i32], ptr addrspace(1) %A, i32 0, i32 2
+  ret ptr addrspace(1) %C
 }
 
-define i32 addrspace(1)* @test33_addrspacecast(%struct.Key* %A) {
+define ptr addrspace(1) @test33_addrspacecast(ptr %A) {
 ; CHECK-LABEL: @test33_addrspacecast(
-; CHECK-NEXT:    [[C:%.*]] = getelementptr [[STRUCT_KEY:%.*]], %struct.Key* [[A:%.*]], i64 0, i32 0, i32 1
-; CHECK-NEXT:    [[TMP1:%.*]] = addrspacecast i32* [[C]] to i32 addrspace(1)*
-; CHECK-NEXT:    ret i32 addrspace(1)* [[TMP1]]
+; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)
+; CHECK-NEXT:    [[C:%.*]] = getelementptr [[STRUCT_ANON:%.*]], ptr addrspace(1) [[B]], i16 0, i32 2
+; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
 ;
-  %B = addrspacecast %struct.Key* %A to %struct.anon addrspace(1)*
-  %C = getelementptr %struct.anon, %struct.anon addrspace(1)* %B, i32 0, i32 2
-  ret i32 addrspace(1)* %C
+  %B = addrspacecast ptr %A to ptr addrspace(1)
+  %C = getelementptr %struct.anon, ptr addrspace(1) %B, i32 0, i32 2
+  ret ptr addrspace(1) %C
 }
 
-  %T2 = type { i8*, i8 }
-define i8* @test34(i8* %Val, i64 %V) nounwind {
+  %T2 = type { ptr, i8 }
+define ptr @test34(ptr %Val, i64 %V) nounwind {
 ; CHECK-LABEL: @test34(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[C_CAST:%.*]] = inttoptr i64 [[V:%.*]] to i8*
-; CHECK-NEXT:    ret i8* [[C_CAST]]
+; CHECK-NEXT:    [[C_CAST:%.*]] = inttoptr i64 [[V:%.*]] to ptr
+; CHECK-NEXT:    ret ptr [[C_CAST]]
 ;
 entry:
   %A = alloca %T2, align 8
-  %mrv_gep = bitcast %T2* %A to i64*
-  %B = getelementptr %T2, %T2* %A, i64 0, i32 0
 
-  store i64 %V, i64* %mrv_gep
-  %C = load i8*, i8** %B, align 8
-  ret i8* %C
+  store i64 %V, ptr %A
+  %C = load ptr, ptr %A, align 8
+  ret ptr %C
 }
 
-%t0 = type { i8*, [19 x i8] }
-%t1 = type { i8*, [0 x i8] }
+%t0 = type { ptr, [19 x i8] }
+%t1 = type { ptr, [0 x i8] }
 
 @array = external global [11 x i8]
 
@@ -796,20 +763,20 @@ entry:
 
 define i32 @test35() nounwind {
 ; CHECK-LABEL: @test35(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 (i8*, ...) @printf(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @"\01LC8", i64 0, i64 0), i8* nonnull getelementptr inbounds ([[T0:%.*]], %t0* @s, i64 0, i32 1, i64 0)) #[[ATTR0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @"\01LC8", ptr nonnull getelementptr inbounds ([[T0:%.*]], ptr @s, i64 0, i32 1, i64 0)) #[[ATTR0]]
 ; CHECK-NEXT:    ret i32 0
 ;
-  call i32 (i8*, ...) @printf(i8* getelementptr ([17 x i8], [17 x i8]* @"\01LC8", i32 0, i32 0),
-  i8* getelementptr (%t1, %t1* bitcast (%t0* @s to %t1*), i32 0, i32 1, i32 0)) nounwind
+  call i32 (ptr, ...) @printf(ptr @"\01LC8",
+  ptr getelementptr (%t1, ptr @s, i32 0, i32 1, i32 0)) nounwind
   ret i32 0
 }
 
 ; Don't treat signed offsets as unsigned.
-define i8* @test36() nounwind {
+define ptr @test36() nounwind {
 ; CHECK-LABEL: @test36(
-; CHECK-NEXT:    ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i64 -1, i64 10)
+; CHECK-NEXT:    ret ptr getelementptr ([11 x i8], ptr @array, i64 -1, i64 10)
 ;
-  ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i32 0, i64 -1)
+  ret ptr getelementptr ([11 x i8], ptr @array, i32 0, i64 -1)
 }
 
 ; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0).
@@ -818,40 +785,38 @@ define i1 @test37() nounwind {
 ; CHECK-LABEL: @test37(
 ; CHECK-NEXT:    ret i1 true
 ;
-  %t = icmp eq i8* getelementptr ([1 x i8], [1 x i8]* @A37, i64 0, i64 1),
-  getelementptr ([1 x i8], [1 x i8]* @A37, i64 1, i64 0)
+  %t = icmp eq ptr getelementptr ([1 x i8], ptr @A37, i64 0, i64 1),
+  getelementptr ([1 x i8], ptr @A37, i64 1, i64 0)
   ret i1 %t
 }
 
 ; Test index promotion
-define i32* @test38(i32* %I, i32 %n) {
+define ptr @test38(ptr %I, i32 %n) {
 ; CHECK-LABEL: @test38(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N:%.*]] to i64
-; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 [[TMP1]]
-; CHECK-NEXT:    ret i32* [[A]]
+; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[TMP1]]
+; CHECK-NEXT:    ret ptr [[A]]
 ;
-  %A = getelementptr i32, i32* %I, i32 %n
-  ret i32* %A
+  %A = getelementptr i32, ptr %I, i32 %n
+  ret ptr %A
 }
 
 ; Test that we don't duplicate work when the second gep is a "bitcast".
-%pr10322_t = type { i8* }
-declare void @pr10322_f2(%pr10322_t*)
-declare void @pr10322_f3(i8**)
-define void @pr10322_f1(%pr10322_t* %foo) {
+%pr10322_t = type { ptr }
+declare void @pr10322_f2(ptr)
+declare void @pr10322_f3(ptr)
+define void @pr10322_f1(ptr %foo) {
 ; CHECK-LABEL: @pr10322_f1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [[PR10322_T:%.*]], %pr10322_t* [[FOO:%.*]], i64 2
-; CHECK-NEXT:    call void @pr10322_f2(%pr10322_t* nonnull [[ARRAYIDX8]]) #[[ATTR0]]
-; CHECK-NEXT:    [[T2:%.*]] = getelementptr inbounds [[PR10322_T]], %pr10322_t* [[ARRAYIDX8]], i64 0, i32 0
-; CHECK-NEXT:    call void @pr10322_f3(i8** nonnull [[T2]]) #[[ATTR0]]
+; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds [[PR10322_T:%.*]], ptr [[FOO:%.*]], i64 2
+; CHECK-NEXT:    call void @pr10322_f2(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]
+; CHECK-NEXT:    call void @pr10322_f3(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]
 ; CHECK-NEXT:    ret void
 ;
 entry:
-  %arrayidx8 = getelementptr inbounds %pr10322_t, %pr10322_t* %foo, i64 2
-  call void @pr10322_f2(%pr10322_t* %arrayidx8) nounwind
-  %t2 = getelementptr inbounds %pr10322_t, %pr10322_t* %arrayidx8, i64 0, i32 0
-  call void @pr10322_f3(i8** %t2) nounwind
+  %arrayidx8 = getelementptr inbounds %pr10322_t, ptr %foo, i64 2
+  call void @pr10322_f2(ptr %arrayidx8) nounwind
+  call void @pr10322_f3(ptr %arrayidx8) nounwind
   ret void
 
 }
@@ -861,147 +826,132 @@ entry:
 %three_gep_t = type {i32}
 %three_gep_t2 = type {%three_gep_t}
 
-define void @three_gep_f(%three_gep_t2* %x) {
+define void @three_gep_f(ptr %x) {
 ; CHECK-LABEL: @three_gep_f(
-; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr [[THREE_GEP_T2:%.*]], %three_gep_t2* [[X:%.*]], i64 2
-; CHECK-NEXT:    call void @three_gep_h(%three_gep_t2* [[GEP1]])
-; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr [[THREE_GEP_T2]], %three_gep_t2* [[GEP1]], i64 0, i32 0, i32 0
-; CHECK-NEXT:    call void @three_gep_g(i32* [[GEP3]])
+; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr [[THREE_GEP_T2:%.*]], ptr [[X:%.*]], i64 2
+; CHECK-NEXT:    call void @three_gep_h(ptr [[GEP1]])
+; CHECK-NEXT:    call void @three_gep_g(ptr [[GEP1]])
 ; CHECK-NEXT:    ret void
 ;
-  %gep1 = getelementptr %three_gep_t2, %three_gep_t2* %x, i64 2
-  call void @three_gep_h(%three_gep_t2* %gep1)
-  %gep2 = getelementptr %three_gep_t2, %three_gep_t2* %gep1, i64 0, i32 0
-  %gep3 = getelementptr %three_gep_t, %three_gep_t* %gep2, i64 0, i32 0
-  call void @three_gep_g(i32* %gep3)
+  %gep1 = getelementptr %three_gep_t2, ptr %x, i64 2
+  call void @three_gep_h(ptr %gep1)
+  call void @three_gep_g(ptr %gep1)
 
   ret void
 }
 
-declare void @three_gep_g(i32*)
-declare void @three_gep_h(%three_gep_t2*)
+declare void @three_gep_g(ptr)
+declare void @three_gep_h(ptr)
 
-%struct.ham = type { i32, %struct.zot*, %struct.zot*, %struct.zot* }
+%struct.ham = type { i32, ptr, ptr, ptr }
 %struct.zot = type { i64, i8 }
 
-define void @test39(%struct.ham* %arg, i8 %arg1) nounwind {
+define void @test39(ptr %arg, i8 %arg1) nounwind {
 ; CHECK-LABEL: @test39(
-; CHECK-NEXT:    [[T:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], %struct.ham* [[ARG:%.*]], i64 0, i32 2
-; CHECK-NEXT:    [[TMP1:%.*]] = bitcast %struct.zot** [[T]] to i8**
-; CHECK-NEXT:    [[T21:%.*]] = load i8*, i8** [[TMP1]], align 8
-; CHECK-NEXT:    [[T4:%.*]] = getelementptr inbounds i8, i8* [[T21]], i64 -8
-; CHECK-NEXT:    store i8 [[ARG1:%.*]], i8* [[T4]], align 8
+; CHECK-NEXT:    [[T:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], ptr [[ARG:%.*]], i64 0, i32 2
+; CHECK-NEXT:    [[T2:%.*]] = load ptr, ptr [[T]], align 8
+; CHECK-NEXT:    [[T4:%.*]] = getelementptr inbounds i8, ptr [[T2]], i64 -8
+; CHECK-NEXT:    store i8 [[ARG1:%.*]], ptr [[T4]], align 8
 ; CHECK-NEXT:    ret void
 ;
-  %t = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 2
-  %t2 = load %struct.zot*, %struct.zot** %t, align 8
-  %t3 = bitcast %struct.zot* %t2 to i8*
-  %t4 = getelementptr inbounds i8, i8* %t3, i64 -8
-  store i8 %arg1, i8* %t4, align 8
+  %t = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 2
+  %t2 = load ptr, ptr %t, align 8
+  %t4 = getelementptr inbounds i8, ptr %t2, i64 -8
+  store i8 %arg1, ptr %t4, align 8
   ret void
 
 }
 
-define i1 @pr16483([1 x i8]* %a, [1 x i8]* %b) {
+define i1 @pr16483(ptr %a, ptr %b) {
 ; CHECK-LABEL: @pr16483(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult [1 x i8]* [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
-  %c = getelementptr [1 x i8], [1 x i8]* %a, i32 0, i32 0
-  %d = getelementptr [1 x i8], [1 x i8]* %b, i32 0, i32 0
-  %cmp = icmp ult i8* %c, %d
+  %cmp = icmp ult ptr %a, %b
   ret i1 %cmp
 
 }
 
-define i8 @test_gep_bitcast_as1(i32 addrspace(1)* %arr, i16 %N) {
+define i8 @test_gep_bitcast_as1(ptr addrspace(1) %arr, i16 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_as1(
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr i32, i32 addrspace(1)* [[ARR:%.*]], i16 [[N:%.*]]
-; CHECK-NEXT:    [[T:%.*]] = bitcast i32 addrspace(1)* [[T1]] to i8 addrspace(1)*
-; CHECK-NEXT:    [[X:%.*]] = load i8, i8 addrspace(1)* [[T]], align 1
+; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 2
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 1
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
-  %cast = bitcast i32 addrspace(1)* %arr to i8 addrspace(1)*
   %V = mul i16 %N, 4
-  %t = getelementptr i8, i8 addrspace(1)* %cast, i16 %V
-  %x = load i8, i8 addrspace(1)* %t
+  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V
+  %x = load i8, ptr addrspace(1) %t
   ret i8 %x
 }
 
 ; The element size of the array matches the element size of the pointer
-define i64 @test_gep_bitcast_array_same_size_element([100 x double]* %arr, i64 %N) {
+define i64 @test_gep_bitcast_array_same_size_element(ptr %arr, i64 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_array_same_size_element(
 ; CHECK-NEXT:    [[V:%.*]] = shl i64 [[N:%.*]], 3
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr [100 x double], [100 x double]* [[ARR:%.*]], i64 0, i64 [[V]]
-; CHECK-NEXT:    [[T:%.*]] = bitcast double* [[T1]] to i64*
-; CHECK-NEXT:    [[X:%.*]] = load i64, i64* [[T]], align 4
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i64, ptr [[ARR:%.*]], i64 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i64, ptr [[T]], align 4
 ; CHECK-NEXT:    ret i64 [[X]]
 ;
-  %cast = bitcast [100 x double]* %arr to i64*
   %V = mul i64 %N, 8
-  %t = getelementptr i64, i64* %cast, i64 %V
-  %x = load i64, i64* %t
+  %t = getelementptr i64, ptr %arr, i64 %V
+  %x = load i64, ptr %t
   ret i64 %x
 }
 
 ; gep should be done in the original address space.
-define i64 @test_gep_bitcast_array_same_size_element_addrspacecast([100 x double]* %arr, i64 %N) {
+define i64 @test_gep_bitcast_array_same_size_element_addrspacecast(ptr %arr, i64 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast(
+; CHECK-NEXT:    [[CAST:%.*]] = addrspacecast ptr [[ARR:%.*]] to ptr addrspace(3)
 ; CHECK-NEXT:    [[V:%.*]] = shl i64 [[N:%.*]], 3
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr [100 x double], [100 x double]* [[ARR:%.*]], i64 0, i64 [[V]]
-; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double* [[T1]] to i64*
-; CHECK-NEXT:    [[T:%.*]] = addrspacecast i64* [[TMP1]] to i64 addrspace(3)*
-; CHECK-NEXT:    [[X:%.*]] = load i64, i64 addrspace(3)* [[T]], align 4
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i64, ptr addrspace(3) [[CAST]], i64 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(3) [[T]], align 4
 ; CHECK-NEXT:    ret i64 [[X]]
 ;
-  %cast = addrspacecast [100 x double]* %arr to i64 addrspace(3)*
+  %cast = addrspacecast ptr %arr to ptr addrspace(3)
   %V = mul i64 %N, 8
-  %t = getelementptr i64, i64 addrspace(3)* %cast, i64 %V
-  %x = load i64, i64 addrspace(3)* %t
+  %t = getelementptr i64, ptr addrspace(3) %cast, i64 %V
+  %x = load i64, ptr addrspace(3) %t
   ret i64 %x
 }
 
 ; The element size of the array is 
diff erent the element size of the pointer
-define i8 @test_gep_bitcast_array_
diff erent_size_element([100 x double]* %arr, i64 %N) {
+define i8 @test_gep_bitcast_array_
diff erent_size_element(ptr %arr, i64 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_array_
diff erent_size_element(
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr [100 x double], [100 x double]* [[ARR:%.*]], i64 0, i64 [[N:%.*]]
-; CHECK-NEXT:    [[T:%.*]] = bitcast double* [[T1]] to i8*
-; CHECK-NEXT:    [[X:%.*]] = load i8, i8* [[T]], align 1
+; CHECK-NEXT:    [[V:%.*]] = shl i64 [[N:%.*]], 3
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr [[ARR:%.*]], i64 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[T]], align 1
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
-  %cast = bitcast [100 x double]* %arr to i8*
   %V = mul i64 %N, 8
-  %t = getelementptr i8, i8* %cast, i64 %V
-  %x = load i8, i8* %t
+  %t = getelementptr i8, ptr %arr, i64 %V
+  %x = load i8, ptr %t
   ret i8 %x
 }
 
-define i64 @test_gep_bitcast_array_same_size_element_as1([100 x double] addrspace(1)* %arr, i16 %N) {
+define i64 @test_gep_bitcast_array_same_size_element_as1(ptr addrspace(1) %arr, i16 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_as1(
 ; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 3
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr [100 x double], [100 x double] addrspace(1)* [[ARR:%.*]], i16 0, i16 [[V]]
-; CHECK-NEXT:    [[T:%.*]] = bitcast double addrspace(1)* [[T1]] to i64 addrspace(1)*
-; CHECK-NEXT:    [[X:%.*]] = load i64, i64 addrspace(1)* [[T]], align 4
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i64, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(1) [[T]], align 4
 ; CHECK-NEXT:    ret i64 [[X]]
 ;
-  %cast = bitcast [100 x double] addrspace(1)* %arr to i64 addrspace(1)*
   %V = mul i16 %N, 8
-  %t = getelementptr i64, i64 addrspace(1)* %cast, i16 %V
-  %x = load i64, i64 addrspace(1)* %t
+  %t = getelementptr i64, ptr addrspace(1) %arr, i16 %V
+  %x = load i64, ptr addrspace(1) %t
   ret i64 %x
 }
 
-define i8 @test_gep_bitcast_array_
diff erent_size_element_as1([100 x double] addrspace(1)* %arr, i16 %N) {
+define i8 @test_gep_bitcast_array_
diff erent_size_element_as1(ptr addrspace(1) %arr, i16 %N) {
 ; CHECK-LABEL: @test_gep_bitcast_array_
diff erent_size_element_as1(
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr [100 x double], [100 x double] addrspace(1)* [[ARR:%.*]], i16 0, i16 [[N:%.*]]
-; CHECK-NEXT:    [[T:%.*]] = bitcast double addrspace(1)* [[T1]] to i8 addrspace(1)*
-; CHECK-NEXT:    [[X:%.*]] = load i8, i8 addrspace(1)* [[T]], align 1
+; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 3
+; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]
+; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 1
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
-  %cast = bitcast [100 x double] addrspace(1)* %arr to i8 addrspace(1)*
   %V = mul i16 %N, 8
-  %t = getelementptr i8, i8 addrspace(1)* %cast, i16 %V
-  %x = load i8, i8 addrspace(1)* %t
+  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V
+  %x = load i8, ptr addrspace(1) %t
   ret i8 %x
 }
 
@@ -1010,228 +960,218 @@ define i64 @test40() {
 ; CHECK-NEXT:    ret i64 8
 ;
   %array = alloca [3 x i32], align 4
-  %gep = getelementptr inbounds [3 x i32], [3 x i32]* %array, i64 0, i64 2
-  %gepi8 = bitcast i32* %gep to i8*
-  %p = ptrtoint [3 x i32]* %array to i64
+  %gep = getelementptr inbounds [3 x i32], ptr %array, i64 0, i64 2
+  %p = ptrtoint ptr %array to i64
   %np = sub i64 0, %p
-  %gep2 = getelementptr i8, i8* %gepi8, i64 %np
-  %ret = ptrtoint i8* %gep2 to i64
+  %gep2 = getelementptr i8, ptr %gep, i64 %np
+  %ret = ptrtoint ptr %gep2 to i64
   ret i64 %ret
 
 }
 
-define i16 @test41([3 x i32] addrspace(1)* %array) {
+define i16 @test41(ptr addrspace(1) %array) {
 ; CHECK-LABEL: @test41(
 ; CHECK-NEXT:    ret i16 8
 ;
-  %gep = getelementptr inbounds [3 x i32], [3 x i32] addrspace(1)* %array, i16 0, i16 2
-  %gepi8 = bitcast i32 addrspace(1)* %gep to i8 addrspace(1)*
-  %p = ptrtoint [3 x i32] addrspace(1)* %array to i16
+  %gep = getelementptr inbounds [3 x i32], ptr addrspace(1) %array, i16 0, i16 2
+  %p = ptrtoint ptr addrspace(1) %array to i16
   %np = sub i16 0, %p
-  %gep2 = getelementptr i8, i8 addrspace(1)* %gepi8, i16 %np
-  %ret = ptrtoint i8 addrspace(1)* %gep2 to i16
+  %gep2 = getelementptr i8, ptr addrspace(1) %gep, i16 %np
+  %ret = ptrtoint ptr addrspace(1) %gep2 to i16
   ret i16 %ret
 
 }
 
-define i8* @test42i(i8* %c1, i8* %c2) {
+define ptr @test42i(ptr %c1, ptr %c2) {
 ; CHECK-LABEL: @test42i(
-; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint i8* [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[C2:%.*]], i64 [[SUB]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C2:%.*]], i64 [[SUB]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint = ptrtoint i8* %c1 to i64
+  %ptrtoint = ptrtoint ptr %c1 to i64
   %sub = sub i64 0, %ptrtoint
-  %gep = getelementptr inbounds i8, i8* %c2, i64 %sub
-  ret i8* %gep
+  %gep = getelementptr inbounds i8, ptr %c2, i64 %sub
+  ret ptr %gep
 
 }
 
-define i8* @test42(i8* %c1, i8* %c2) {
+define ptr @test42(ptr %c1, ptr %c2) {
 ; CHECK-LABEL: @test42(
-; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint i8* [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* [[C2:%.*]], i64 [[SUB]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[C2:%.*]], i64 [[SUB]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint = ptrtoint i8* %c1 to i64
+  %ptrtoint = ptrtoint ptr %c1 to i64
   %sub = sub i64 0, %ptrtoint
-  %gep = getelementptr i8, i8* %c2, i64 %sub
-  ret i8* %gep
+  %gep = getelementptr i8, ptr %c2, i64 %sub
+  ret ptr %gep
 
 }
 
-define i16* @test43i(i16* %c1, i16* %c2) {
+define ptr @test43i(ptr %c1, ptr %c2) {
 ; CHECK-LABEL: @test43i(
-; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint i16* [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
 ; CHECK-NEXT:    [[SHR:%.*]] = ashr i64 [[SUB]], 1
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, i16* [[C2:%.*]], i64 [[SHR]]
-; CHECK-NEXT:    ret i16* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, ptr [[C2:%.*]], i64 [[SHR]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint = ptrtoint i16* %c1 to i64
+  %ptrtoint = ptrtoint ptr %c1 to i64
   %sub = sub i64 0, %ptrtoint
   %shr = ashr i64 %sub, 1
-  %gep = getelementptr inbounds i16, i16* %c2, i64 %shr
-  ret i16* %gep
+  %gep = getelementptr inbounds i16, ptr %c2, i64 %shr
+  ret ptr %gep
 
 }
 
-define %struct.C* @test44i(%struct.C* %c1, %struct.C* %c2) {
+define ptr @test44i(ptr %c1, ptr %c2) {
 ; CHECK-LABEL: @test44i(
-; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint %struct.C* [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
 ; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 7
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], %struct.C* [[C2:%.*]], i64 [[SHR]]
-; CHECK-NEXT:    ret %struct.C* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SHR]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint = ptrtoint %struct.C* %c1 to i64
+  %ptrtoint = ptrtoint ptr %c1 to i64
   %sub = sub i64 0, %ptrtoint
   %shr = sdiv i64 %sub, 7
-  %gep = getelementptr inbounds %struct.C, %struct.C* %c2, i64 %shr
-  ret %struct.C* %gep
+  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %shr
+  ret ptr %gep
 
 }
 
-define %struct.C* @test45(%struct.C* %c1, %struct.C** %c2) {
+define ptr @test45(ptr %c1, ptr %c2) {
 ; CHECK-LABEL: @test45(
-; CHECK-NEXT:    [[PTRTOINT1:%.*]] = ptrtoint %struct.C* [[C1:%.*]] to i64
-; CHECK-NEXT:    [[PTRTOINT2:%.*]] = ptrtoint %struct.C** [[C2:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT1:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT2:%.*]] = ptrtoint ptr [[C2:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[PTRTOINT2]], [[PTRTOINT1]]
 ; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 7
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], %struct.C* [[C1]], i64 [[SHR]]
-; CHECK-NEXT:    ret %struct.C* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C1]], i64 [[SHR]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint1 = ptrtoint %struct.C* %c1 to i64
-  %ptrtoint2 = ptrtoint %struct.C** %c2 to i64
+  %ptrtoint1 = ptrtoint ptr %c1 to i64
+  %ptrtoint2 = ptrtoint ptr %c2 to i64
   %sub = sub i64 %ptrtoint2, %ptrtoint1 ; C2 - C1
   %shr = sdiv i64 %sub, 7
-  %gep = getelementptr inbounds %struct.C, %struct.C* %c1, i64 %shr ; C1 + (C2 - C1)
-  ret %struct.C* %gep
+  %gep = getelementptr inbounds %struct.C, ptr %c1, i64 %shr ; C1 + (C2 - C1)
+  ret ptr %gep
 }
 
-define %struct.C* @test46(%struct.C* %c1, %struct.C* %c2, i64 %N) {
+define ptr @test46(ptr %c1, ptr %c2, i64 %N) {
 ; CHECK-LABEL: @test46(
-; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint %struct.C* [[C1:%.*]] to i64
+; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
 ; CHECK-NEXT:    [[SDIV:%.*]] = sdiv i64 [[SUB]], [[N:%.*]]
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], %struct.C* [[C2:%.*]], i64 [[SDIV]]
-; CHECK-NEXT:    ret %struct.C* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SDIV]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %ptrtoint = ptrtoint %struct.C* %c1 to i64
+  %ptrtoint = ptrtoint ptr %c1 to i64
   %sub = sub i64 0, %ptrtoint
   %sdiv = sdiv i64 %sub, %N
-  %gep = getelementptr inbounds %struct.C, %struct.C* %c2, i64 %sdiv
-  ret %struct.C* %gep
+  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %sdiv
+  ret ptr %gep
 
 }
 
-define i32* @test47(i32* %I, i64 %C, i64 %D) {
+define ptr @test47(ptr %I, i64 %C, i64 %D) {
 ; CHECK-LABEL: @test47(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 [[D:%.*]]
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]
+; CHECK-NEXT:    ret ptr [[B]]
 ;
   %sub = sub i64 %D, %C
-  %A = getelementptr i32, i32* %I, i64 %C
-  %B = getelementptr i32, i32* %A, i64 %sub
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i64 %C
+  %B = getelementptr i32, ptr %A, i64 %sub
+  ret ptr %B
 }
 
-define i32* @test48(i32* %I, i64 %C, i64 %D) {
+define ptr @test48(ptr %I, i64 %C, i64 %D) {
 ; CHECK-LABEL: @test48(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 [[D:%.*]]
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]
+; CHECK-NEXT:    ret ptr [[B]]
 ;
   %sub = sub i64 %D, %C
-  %A = getelementptr i32, i32* %I, i64 %sub
-  %B = getelementptr i32, i32* %A, i64 %C
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i64 %sub
+  %B = getelementptr i32, ptr %A, i64 %C
+  ret ptr %B
 }
 
-define i32* @test49(i32* %I, i64 %C) {
+define ptr @test49(ptr %I, i64 %C) {
 ; CHECK-LABEL: @test49(
-; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, i32* [[I:%.*]], i64 -1
-; CHECK-NEXT:    ret i32* [[B]]
+; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 -1
+; CHECK-NEXT:    ret ptr [[B]]
 ;
   %notC = xor i64 -1, %C
-  %A = getelementptr i32, i32* %I, i64 %C
-  %B = getelementptr i32, i32* %A, i64 %notC
-  ret i32* %B
+  %A = getelementptr i32, ptr %I, i64 %C
+  %B = getelementptr i32, ptr %A, i64 %notC
+  ret ptr %B
 }
 
-define i32 addrspace(1)* @ascast_0_gep(i32* %p) nounwind {
+define ptr addrspace(1) @ascast_0_gep(ptr %p) nounwind {
 ; CHECK-LABEL: @ascast_0_gep(
-; CHECK-NEXT:    [[X:%.*]] = addrspacecast i32* [[P:%.*]] to i32 addrspace(1)*
-; CHECK-NEXT:    ret i32 addrspace(1)* [[X]]
+; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)
+; CHECK-NEXT:    ret ptr addrspace(1) [[X]]
 ;
-  %gep = getelementptr i32, i32* %p, i32 0
-  %x = addrspacecast i32* %gep to i32 addrspace(1)*
-  ret i32 addrspace(1)* %x
+  %x = addrspacecast ptr %p to ptr addrspace(1)
+  ret ptr addrspace(1) %x
 }
 
 ; Do not merge the GEP and the addrspacecast, because it would undo the
 ; addrspacecast canonicalization.
-define i32 addrspace(1)* @ascast_0_0_gep([128 x i32]* %p) nounwind {
+define ptr addrspace(1) @ascast_0_0_gep(ptr %p) nounwind {
 ; CHECK-LABEL: @ascast_0_0_gep(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [128 x i32], [128 x i32]* [[P:%.*]], i64 0, i64 0
-; CHECK-NEXT:    [[X:%.*]] = addrspacecast i32* [[GEP]] to i32 addrspace(1)*
-; CHECK-NEXT:    ret i32 addrspace(1)* [[X]]
+; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)
+; CHECK-NEXT:    ret ptr addrspace(1) [[X]]
 ;
-  %gep = getelementptr [128 x i32], [128 x i32]* %p, i32 0, i32 0
-  %x = addrspacecast i32* %gep to i32 addrspace(1)*
-  ret i32 addrspace(1)* %x
+  %x = addrspacecast ptr %p to ptr addrspace(1)
+  ret ptr addrspace(1) %x
 }
 
-define <2 x i32*> @PR32414(i32** %ptr) {
+define <2 x ptr> @PR32414(ptr %ptr) {
 ; CHECK-LABEL: @PR32414(
-; CHECK-NEXT:    [[T0:%.*]] = bitcast i32** [[PTR:%.*]] to i32*
-; CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], <2 x i64> <i64 0, i64 1>
-; CHECK-NEXT:    ret <2 x i32*> [[T1]]
+; CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], <2 x i64> <i64 0, i64 1>
+; CHECK-NEXT:    ret <2 x ptr> [[T1]]
 ;
-  %t0 = bitcast i32** %ptr to i32*
-  %t1 = getelementptr inbounds i32, i32* %t0, <2 x i64> <i64 0, i64 1>
-  ret <2 x i32*> %t1
+  %t1 = getelementptr inbounds i32, ptr %ptr, <2 x i64> <i64 0, i64 1>
+  ret <2 x ptr> %t1
 }
 
-define i32* @test_bitcast_nzgep([1 x i32]* %base, i64 %idx) {
+define ptr @test_bitcast_nzgep(ptr %base, i64 %idx) {
 ; CHECK-LABEL: @test_bitcast_nzgep(
-; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[BASE:%.*]], i64 0, i64 [[IDX:%.*]]
-; CHECK-NEXT:    ret i32* [[PTR]]
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[PTR]]
 ;
-  %base2 = bitcast [1 x i32]* %base to i32*
-  %ptr = getelementptr inbounds i32, i32* %base2, i64 %idx
-  ret i32* %ptr
+  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx
+  ret ptr %ptr
 }
 
-define i32* @test_zgep_nzgep([1 x i32]* %base, i64 %idx) {
+define ptr @test_zgep_nzgep(ptr %base, i64 %idx) {
 ; CHECK-LABEL: @test_zgep_nzgep(
-; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[BASE:%.*]], i64 0, i64 [[IDX:%.*]]
-; CHECK-NEXT:    ret i32* [[PTR]]
+; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[PTR]]
 ;
-  %base2 = getelementptr [1 x i32], [1 x i32]* %base, i64 0, i64 0
-  %ptr = getelementptr inbounds i32, i32* %base2, i64 %idx
-  ret i32* %ptr
+  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx
+  ret ptr %ptr
 }
 
-define i32* @test_nzgep_zgep([1 x i32]* %base, i64 %idx) {
+define ptr @test_nzgep_zgep(ptr %base, i64 %idx) {
 ; CHECK-LABEL: @test_nzgep_zgep(
-; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[BASE:%.*]], i64 [[IDX:%.*]], i64 0
-; CHECK-NEXT:    ret i32* [[PTR]]
+; CHECK-NEXT:    [[BASE2:%.*]] = getelementptr inbounds [1 x i32], ptr [[BASE:%.*]], i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[BASE2]]
 ;
-  %base2 = getelementptr inbounds [1 x i32], [1 x i32]* %base, i64 %idx
-  %ptr = getelementptr [1 x i32], [1 x i32]* %base2, i64 0, i64 0
-  ret i32* %ptr
+  %base2 = getelementptr inbounds [1 x i32], ptr %base, i64 %idx
+  ret ptr %base2
 }
 
-define i32* @test_gep_inbounds_of_gep(i32* %base) {
+define ptr @test_gep_inbounds_of_gep(ptr %base) {
 ; CHECK-LABEL: @test_gep_inbounds_of_gep(
-; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i32, i32* [[BASE:%.*]], i64 8
-; CHECK-NEXT:    ret i32* [[PTR2]]
+; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 8
+; CHECK-NEXT:    ret ptr [[PTR2]]
 ;
-  %ptr1 = getelementptr i32, i32* %base, i64 4
-  %ptr2 = getelementptr inbounds i32, i32* %ptr1, i64 4
-  ret i32* %ptr2
+  %ptr1 = getelementptr i32, ptr %base, i64 4
+  %ptr2 = getelementptr inbounds i32, ptr %ptr1, i64 4
+  ret ptr %ptr2
 }
 
 %struct.f = type { i32 }
@@ -1239,96 +1179,90 @@ define i32* @test_gep_inbounds_of_gep(i32* %base) {
 @g0 = internal unnamed_addr constant %struct.f zeroinitializer, align 4
 @g1 = internal unnamed_addr constant %struct.f { i32 -1 }, align 4
 
-define i32* @PR45084(i1 %cond) {
+define ptr @PR45084(i1 %cond) {
 ; CHECK-LABEL: @PR45084(
-; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[COND:%.*]], i32* getelementptr inbounds ([[STRUCT_F:%.*]], %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds ([[STRUCT_F]], %struct.f* @g1, i64 0, i32 0), !prof [[PROF0:![0-9]+]]
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g1, !prof [[PROF0:![0-9]+]]
+; CHECK-NEXT:    ret ptr [[SEL]]
 ;
-  %sel = select i1 %cond, %struct.f* @g0, %struct.f* @g1, !prof !0
-  %gep = getelementptr inbounds %struct.f, %struct.f* %sel, i64 0, i32 0
-  ret i32* %gep
+  %sel = select i1 %cond, ptr @g0, ptr @g1, !prof !0
+  ret ptr %sel
 }
 
-define i32* @PR45084_extra_use(i1 %cond, %struct.f** %p) {
+define ptr @PR45084_extra_use(i1 %cond, ptr %p) {
 ; CHECK-LABEL: @PR45084_extra_use(
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], %struct.f* @g0, %struct.f* @g1
-; CHECK-NEXT:    store %struct.f* [[SEL]], %struct.f** [[P:%.*]], align 8
-; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[COND]], i32* getelementptr inbounds ([[STRUCT_F:%.*]], %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds ([[STRUCT_F]], %struct.f* @g1, i64 0, i32 0)
-; CHECK-NEXT:    ret i32* [[GEP]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g1
+; CHECK-NEXT:    store ptr [[SEL]], ptr [[P:%.*]], align 8
+; CHECK-NEXT:    ret ptr [[SEL]]
 ;
-  %sel = select i1 %cond, %struct.f* @g0, %struct.f* @g1
-  store %struct.f* %sel, %struct.f** %p
-  %gep = getelementptr %struct.f, %struct.f* %sel, i64 0, i32 0
-  ret i32* %gep
+  %sel = select i1 %cond, ptr @g0, ptr @g1
+  store ptr %sel, ptr %p
+  ret ptr %sel
 }
 
-define i8* @gep_null_inbounds(i64 %idx) {
+define ptr @gep_null_inbounds(i64 %idx) {
 ; CHECK-LABEL: @gep_null_inbounds(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* null, i64 [[IDX:%.*]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %gep = getelementptr inbounds i8, i8* null, i64 %idx
-  ret i8* %gep
+  %gep = getelementptr inbounds i8, ptr null, i64 %idx
+  ret ptr %gep
 }
 
-define i8* @gep_null_not_inbounds(i64 %idx) {
+define ptr @gep_null_not_inbounds(i64 %idx) {
 ; CHECK-LABEL: @gep_null_not_inbounds(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* null, i64 [[IDX:%.*]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr null, i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %gep = getelementptr i8, i8* null, i64 %idx
-  ret i8* %gep
+  %gep = getelementptr i8, ptr null, i64 %idx
+  ret ptr %gep
 }
 
-define i8* @gep_null_defined(i64 %idx) null_pointer_is_valid {
+define ptr @gep_null_defined(i64 %idx) null_pointer_is_valid {
 ; CHECK-LABEL: @gep_null_defined(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* null, i64 [[IDX:%.*]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %gep = getelementptr inbounds i8, i8* null, i64 %idx
-  ret i8* %gep
+  %gep = getelementptr inbounds i8, ptr null, i64 %idx
+  ret ptr %gep
 }
 
-define i8* @gep_null_inbounds_
diff erent_type(i64 %idx1, i64 %idx2) {
+define ptr @gep_null_inbounds_
diff erent_type(i64 %idx1, i64 %idx2) {
 ; CHECK-LABEL: @gep_null_inbounds_
diff erent_type(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* null, i64 0, i64 [[IDX2:%.*]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [0 x i8], ptr null, i64 0, i64 [[IDX2:%.*]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %gep = getelementptr inbounds [0 x i8], [0 x i8]* null, i64 %idx1, i64 %idx2
-  ret i8* %gep
+  %gep = getelementptr inbounds [0 x i8], ptr null, i64 %idx1, i64 %idx2
+  ret ptr %gep
 }
 
-define i8* @D98588(i8* %c1, i64 %offset) {
+define ptr @D98588(ptr %c1, i64 %offset) {
 ; CHECK-LABEL: @D98588(
 ; CHECK-NEXT:    [[C2_NEXT_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 3
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[C1:%.*]], i64 [[C2_NEXT_IDX]]
-; CHECK-NEXT:    ret i8* [[GEP]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C1:%.*]], i64 [[C2_NEXT_IDX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
 ;
-  %c2 = bitcast i8* %c1 to i64*
-  %c2_next = getelementptr inbounds i64, i64* %c2, i64 %offset
-  %ptrtoint1 = ptrtoint i8* %c1 to i64
-  %ptrtoint2 = ptrtoint i64* %c2_next to i64
+  %c2_next = getelementptr inbounds i64, ptr %c1, i64 %offset
+  %ptrtoint1 = ptrtoint ptr %c1 to i64
+  %ptrtoint2 = ptrtoint ptr %c2_next to i64
   %sub = sub i64 %ptrtoint2, %ptrtoint1 ; C2 - C1
-  %gep = getelementptr inbounds i8, i8* %c1, i64 %sub ; C1 + (C2 - C1)
-  ret i8* %gep
+  %gep = getelementptr inbounds i8, ptr %c1, i64 %sub ; C1 + (C2 - C1)
+  ret ptr %gep
 }
 
-declare noalias i8* @malloc(i64) nounwind allockind("alloc,uninitialized") allocsize(0)
+declare noalias ptr @malloc(i64) nounwind allockind("alloc,uninitialized") allocsize(0)
 
-define i32 @test_gep_bitcast_malloc(%struct.A* %a) {
+define i32 @test_gep_bitcast_malloc(ptr %a) {
 ; CHECK-LABEL: @test_gep_bitcast_malloc(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[CALL:%.*]] = call noalias dereferenceable_or_null(16) i8* @malloc(i64 16)
-; CHECK-NEXT:    [[B:%.*]] = bitcast i8* [[CALL]] to %struct.A*
-; CHECK-NEXT:    [[G3:%.*]] = getelementptr [[STRUCT_A:%.*]], %struct.A* [[B]], i64 0, i32 2
-; CHECK-NEXT:    [[A_C:%.*]] = load i32, i32* [[G3]], align 4
+; CHECK-NEXT:    [[CALL:%.*]] = call noalias dereferenceable_or_null(16) ptr @malloc(i64 16)
+; CHECK-NEXT:    [[G3:%.*]] = getelementptr [[STRUCT_A:%.*]], ptr [[CALL]], i64 0, i32 2
+; CHECK-NEXT:    [[A_C:%.*]] = load i32, ptr [[G3]], align 4
 ; CHECK-NEXT:    ret i32 [[A_C]]
 ;
 entry:
-  %call = call noalias i8* @malloc(i64 16) #2
-  %B = bitcast i8* %call to %struct.A*
-  %g3 = getelementptr %struct.A, %struct.A* %B, i32 0, i32 2
-  %a_c = load i32, i32* %g3, align 4
+  %call = call noalias ptr @malloc(i64 16) #2
+  %g3 = getelementptr %struct.A, ptr %call, i32 0, i32 2
+  %a_c = load i32, ptr %g3, align 4
   ret i32 %a_c
 }
 


        


More information about the llvm-commits mailing list