; CHECK-LABEL: @test_neg_read_after(
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: ret i32 [[RES]]
;
; CHECK-LABEL: @test_neg_infinite_loop(
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR4:[0-9]+]]
; CHECK-NEXT: ret void
;
%a = alloca i32, align 4
; CHECK-LABEL: @test_neg_throw(
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR5:[0-9]+]]
; CHECK-NEXT: ret void
;
%a = alloca i32, align 4
; CHECK-LABEL: @test_neg_extra_write(
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: ret void
;
%a = alloca i32, align 4
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
-; CHECK-NEXT: call void @f2(i8* nocapture nonnull writeonly [[BITCAST]], i8* nonnull [[BITCAST2]]) #[[ATTR1]]
+; CHECK-NEXT: call void @f2(i8* nocapture nonnull writeonly [[BITCAST]], i8* nonnull [[BITCAST2]]) #[[ATTR3]]
; CHECK-NEXT: ret void
;
%a = alloca i32, align 4
; CHECK-NEXT: [[A2:%.*]] = alloca i8*, align 8
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i8** [[A2]] to i8*
-; CHECK-NEXT: call void @f2(i8* nonnull writeonly [[BITCAST]], i8* nonnull [[BITCAST2]]) #[[ATTR1]]
+; CHECK-NEXT: call void @f2(i8* nonnull writeonly [[BITCAST]], i8* nonnull [[BITCAST2]]) #[[ATTR3]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8** [[A2]] to i32**
; CHECK-NEXT: [[A_COPY_CAST1:%.*]] = load i32*, i32** [[TMP1]], align 8
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A_COPY_CAST1]], align 4
; CHECK-LABEL: @test_neg_captured_before(
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR1]]
+; CHECK-NEXT: call void @f(i8* nocapture nonnull writeonly [[BITCAST]]) #[[ATTR3]]
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: ret i32 [[RES]]
;
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
-; CHECK-NEXT: [[CAPTURE:%.*]] = call i8* @f3(i8* nocapture nonnull writeonly [[BITCAST]], i8* nonnull readonly [[BITCAST2]]) #[[ATTR1]]
+; CHECK-NEXT: [[CAPTURE:%.*]] = call i8* @f3(i8* nocapture nonnull writeonly [[BITCAST]], i8* nonnull readonly [[BITCAST2]]) #[[ATTR3]]
; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[CAPTURE]], align 1
; CHECK-NEXT: ret i8 [[V]]
;
ret void
}
+
+declare void @removable_readnone() readnone nounwind willreturn
+declare void @removable_ro() readonly nounwind willreturn
+
+define void @test_readnone() {
+; CHECK-LABEL: @test_readnone(
+; CHECK-NEXT: ret void
+;
+ call void @removable_readnone()
+ ret void
+}
+
+define void @test_readnone_with_deopt() {
+; CHECK-LABEL: @test_readnone_with_deopt(
+; CHECK-NEXT: call void @removable_readnone() [ "deopt"() ]
+; CHECK-NEXT: ret void
+;
+ call void @removable_readnone() [ "deopt"() ]
+ ret void
+}
+
+define void @test_readonly() {
+; CHECK-LABEL: @test_readonly(
+; CHECK-NEXT: ret void
+;
+ call void @removable_ro()
+ ret void
+}
+
+define void @test_readonly_with_deopt() {
+; CHECK-LABEL: @test_readonly_with_deopt(
+; CHECK-NEXT: ret void
+;
+ call void @removable_ro() [ "deopt"() ]
+ ret void
+}