}
declare i32 @unknown(i32* %dest)
+declare i32 @unknown.as2(i32 addrspace(2)* %dest)
-define i32 @sink_to_use(i1 %c) {
-; CHECK-LABEL: @sink_to_use(
+define i32 @sink_write_to_use(i1 %c) {
+; CHECK-LABEL: @sink_write_to_use(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull writeonly [[VAR]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
+; CHECK: early_return:
+; CHECK-NEXT: ret i32 0
+; CHECK: use_block:
+; CHECK-NEXT: ret i32 [[VAR3]]
+;
+entry:
+ %var = alloca i32, align 4
+ %var3 = call i32 @unknown(i32* writeonly %var) argmemonly nounwind willreturn
+ br i1 %c, label %early_return, label %use_block
+
+early_return:
+ ret i32 0
+
+use_block:
+ ret i32 %var3
+}
+
+define i32 @sink_readwrite_to_use(i1 %c) {
+; CHECK-LABEL: @sink_readwrite_to_use(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
; CHECK: early_return:
; CHECK-NEXT: ret i32 0
ret i32 %var3
}
+define i32 @sink_bitcast(i1 %c) {
+; CHECK-LABEL: @sink_bitcast(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[VAR:%.*]] = alloca i8, align 8
+; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i8* [[VAR]] to i32*
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[BITCAST]]) #[[ATTR1]]
+; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
+; CHECK: early_return:
+; CHECK-NEXT: ret i32 0
+; CHECK: use_block:
+; CHECK-NEXT: ret i32 [[VAR3]]
+;
+entry:
+ %var = alloca i8, align 8
+ %bitcast = bitcast i8* %var to i32*
+ %var3 = call i32 @unknown(i32* %bitcast) argmemonly nounwind willreturn
+ br i1 %c, label %early_return, label %use_block
+
+early_return:
+ ret i32 0
+
+use_block:
+ ret i32 %var3
+}
+
+
+define i32 @sink_gep1(i1 %c) {
+; CHECK-LABEL: @sink_gep1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[VAR1:%.*]] = alloca [2 x i32], align 8
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VAR1]], i64 0, i64 1
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[GEP]]) #[[ATTR1]]
+; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
+; CHECK: early_return:
+; CHECK-NEXT: ret i32 0
+; CHECK: use_block:
+; CHECK-NEXT: ret i32 [[VAR3]]
+;
+entry:
+ %var = alloca i64, align 8
+ %bitcast = bitcast i64* %var to i32*
+ %gep = getelementptr i32, i32* %bitcast, i32 1
+ %var3 = call i32 @unknown(i32* %gep) argmemonly nounwind willreturn
+ br i1 %c, label %early_return, label %use_block
+
+early_return:
+ ret i32 0
+
+use_block:
+ ret i32 %var3
+}
+
+define i32 @sink_gep2(i1 %c) {
+; CHECK-LABEL: @sink_gep2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[VAR1:%.*]] = alloca [2 x i32], align 8
+; CHECK-NEXT: [[VAR1_SUB:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VAR1]], i64 0, i64 0
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR1_SUB]]) #[[ATTR1]]
+; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
+; CHECK: early_return:
+; CHECK-NEXT: ret i32 0
+; CHECK: use_block:
+; CHECK-NEXT: ret i32 [[VAR3]]
+;
+entry:
+ %var = alloca i64, align 8
+ %bitcast = bitcast i64* %var to i32*
+ %var3 = call i32 @unknown(i32* %bitcast) argmemonly nounwind willreturn
+ br i1 %c, label %early_return, label %use_block
+
+early_return:
+ ret i32 0
+
+use_block:
+ ret i32 %var3
+}
+
+define i32 @sink_addrspacecast(i1 %c) {
+; CHECK-LABEL: @sink_addrspacecast(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 8
+; CHECK-NEXT: [[CAST:%.*]] = addrspacecast i32* [[VAR]] to i32 addrspace(2)*
+; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown.as2(i32 addrspace(2)* [[CAST]]) #[[ATTR1]]
+; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
+; CHECK: early_return:
+; CHECK-NEXT: ret i32 0
+; CHECK: use_block:
+; CHECK-NEXT: ret i32 [[VAR3]]
+;
+entry:
+ %var = alloca i32, align 8
+ %cast = addrspacecast i32* %var to i32 addrspace(2)*
+ %var3 = call i32 @unknown.as2(i32 addrspace(2)* %cast) argmemonly nounwind willreturn
+ br i1 %c, label %early_return, label %use_block
+
+early_return:
+ ret i32 0
+
+use_block:
+ ret i32 %var3
+}
+
define i32 @neg_infinite_loop(i1 %c) {
; CHECK-LABEL: @neg_infinite_loop(
; CHECK-NEXT: entry: