288 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 | 
						|
; RUN: opt -gvn -S < %s | FileCheck %s
 | 
						|
 | 
						|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
 | 
						|
target triple = "x86_64-unknown-linux-gnu"
 | 
						|
 | 
						|
define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) {
 | 
						|
; CHECK-LABEL: @f0(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    store i64 [[VAL:%.*]], i64* [[LOC:%.*]]
 | 
						|
; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
 | 
						|
; CHECK:       neverTaken:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i64* [[LOC]] to i8 addrspace(4)**
 | 
						|
; CHECK-NEXT:    [[PTR:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)** [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    store i8 5, i8 addrspace(4)* [[PTR]]
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
; CHECK:       alwaysTaken:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  store i64 %val, i64* %loc
 | 
						|
  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
 | 
						|
 | 
						|
  neverTaken:
 | 
						|
  %loc.bc = bitcast i64* %loc to i8 addrspace(4)**
 | 
						|
  %ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc
 | 
						|
  store i8 5, i8 addrspace(4)* %ptr
 | 
						|
  ret void
 | 
						|
 | 
						|
  alwaysTaken:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
 | 
						|
; CHECK-LABEL: @f1(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    store i8 addrspace(4)* [[VAL:%.*]], i8 addrspace(4)** [[LOC:%.*]]
 | 
						|
; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
 | 
						|
; CHECK:       neverTaken:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)** [[LOC]] to i64*
 | 
						|
; CHECK-NEXT:    [[INT:%.*]] = load i64, i64* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    ret i64 [[INT]]
 | 
						|
; CHECK:       alwaysTaken:
 | 
						|
; CHECK-NEXT:    ret i64 42
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
 | 
						|
  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
 | 
						|
 | 
						|
  neverTaken:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)** %loc to i64*
 | 
						|
  %int = load i64, i64* %loc.bc
 | 
						|
  ret i64 %int
 | 
						|
 | 
						|
  alwaysTaken:
 | 
						|
  ret i64 42
 | 
						|
}
 | 
						|
 | 
						|
;; Note: For terseness, we stop using the %alwaysfalse trick for the
 | 
						|
;; tests below and just exercise the bits of forwarding logic directly.
 | 
						|
 | 
						|
declare void @llvm.memset.p4i8.i64(i8 addrspace(4)* nocapture, i8, i64, i1) nounwind
 | 
						|
 | 
						|
; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
 | 
						|
define i8 addrspace(4)* @neg_forward_memset(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_memset(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
define <1 x i8 addrspace(4)*> @neg_forward_memset_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_memset_vload(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
 | 
						|
  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
 | 
						|
  ret <1 x i8 addrspace(4)*> %ref
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
; Can forward since we can do so w/o breaking types
 | 
						|
define i8 addrspace(4)* @forward_memset_zero(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @forward_memset_zero(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 0, i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* null
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 0, i64 8, i1 false)
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
 | 
						|
define i8 addrspace(4)* @neg_forward_store(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_store(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
 | 
						|
; CHECK-NEXT:    store i64 5, i64 addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
 | 
						|
  store i64 5, i64 addrspace(4)* %loc.bc
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
define <1 x i8 addrspace(4)*> @neg_forward_store_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_store_vload(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
 | 
						|
; CHECK-NEXT:    store i64 5, i64 addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i64 addrspace(4)*
 | 
						|
  store i64 5, i64 addrspace(4)* %loc.bc
 | 
						|
  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
 | 
						|
  ret <1 x i8 addrspace(4)*> %ref
 | 
						|
}
 | 
						|
 | 
						|
; Nulls have known bit patterns, so we can forward
 | 
						|
define i8 addrspace(4)* @forward_store_zero(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @forward_store_zero(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
 | 
						|
; CHECK-NEXT:    store i64 0, i64 addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* null
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
 | 
						|
  store i64 0, i64 addrspace(4)* %loc.bc
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
; Nulls have known bit patterns, so we can forward
 | 
						|
define i8 addrspace(4)* @forward_store_zero2(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @forward_store_zero2(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i32> addrspace(4)*
 | 
						|
; CHECK-NEXT:    store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* null
 | 
						|
;
 | 
						|
  entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i32> addrspace(4)*
 | 
						|
  store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* %loc.bc
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
@NonZeroConstant = constant <4 x i64> <i64 3, i64 3, i64 3, i64 3>
 | 
						|
@ZeroConstant = constant <4 x i64> zeroinitializer
 | 
						|
 | 
						|
 | 
						|
; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
 | 
						|
define i8 addrspace(4)* @neg_forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_memcopy(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
 | 
						|
  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
define <1 x i8 addrspace(4)*> @neg_forward_memcpy_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_forward_memcpy_vload(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
 | 
						|
  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
 | 
						|
  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
 | 
						|
  ret <1 x i8 addrspace(4)*> %ref
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
; Can forward since we can do so w/o breaking types
 | 
						|
; TODO: missed optimization
 | 
						|
define i8 addrspace(4)* @forward_memcpy_zero(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @forward_memcpy_zero(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
 | 
						|
; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @ZeroConstant to i8*), i64 8, i1 false)
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
 | 
						|
  %src.bc = bitcast <4 x i64>* @ZeroConstant to i8*
 | 
						|
  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
declare void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* nocapture, i8* nocapture, i64, i1) nounwind
 | 
						|
 | 
						|
 | 
						|
; Same as the neg_forward_store cases, but for non defs.
 | 
						|
; (Pretend we wrote out the alwaysfalse idiom above.)
 | 
						|
define i8 addrspace(4)* @neg_store_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_store_clobber(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
 | 
						|
; CHECK-NEXT:    store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
 | 
						|
  store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* %loc.bc
 | 
						|
  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
declare void @use(<2 x i64>) inaccessiblememonly
 | 
						|
 | 
						|
; Same as the neg_forward_store cases, but for non defs.
 | 
						|
; (Pretend we wrote out the alwaysfalse idiom above.)
 | 
						|
define i8 addrspace(4)* @neg_load_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @neg_load_clobber(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
 | 
						|
; CHECK-NEXT:    [[V:%.*]] = load <2 x i64>, <2 x i64> addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    call void @use(<2 x i64> [[V]])
 | 
						|
; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
 | 
						|
; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]]
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
 | 
						|
  %v = load <2 x i64>, <2 x i64> addrspace(4)* %loc.bc
 | 
						|
  call void @use(<2 x i64> %v)
 | 
						|
  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 | 
						|
 | 
						|
define i8 addrspace(4)* @store_clobber_zero(i8 addrspace(4)* addrspace(4)* %loc) {
 | 
						|
; CHECK-LABEL: @store_clobber_zero(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
 | 
						|
; CHECK-NEXT:    store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* [[LOC_BC]]
 | 
						|
; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
 | 
						|
; CHECK-NEXT:    ret i8 addrspace(4)* null
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
 | 
						|
  store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* %loc.bc
 | 
						|
  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
 | 
						|
  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
 | 
						|
  ret i8 addrspace(4)* %ref
 | 
						|
}
 |