Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
define i1 @invokecaller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@invokecaller
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #0 personality i32 (...)* @__gxx_personality_v0
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0:#.*]] personality i32 (...)* @__gxx_personality_v0
; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]])
; IS__TUNIT____-NEXT: br label [[OK:%.*]]
; IS__TUNIT____: OK:
Expand All @@ -19,7 +19,7 @@ define i1 @invokecaller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@invokecaller
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #0 personality i32 (...)* @__gxx_personality_v0
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0:#.*]] personality i32 (...)* @__gxx_personality_v0
; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]])
; IS__CGSCC____-NEXT: br label [[OK:%.*]]
; IS__CGSCC____: OK:
Expand Down
52 changes: 26 additions & 26 deletions llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@ define internal %0 @foo(i1 %Q) {
; IS__TUNIT____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT____: T:
; IS__TUNIT____-NEXT: [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
; IS__TUNIT____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] %mrv1
; IS__TUNIT____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] [[MRV]], i32 22, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] [[MRV1]]
; IS__TUNIT____: F:
; IS__TUNIT____-NEXT: [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
; IS__TUNIT____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] %mrv3
; IS__TUNIT____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] [[MRV2]], i32 23, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] [[MRV3]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
; IS__CGSCC____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: T:
; IS__CGSCC____-NEXT: [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
; IS__CGSCC____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] %mrv1
; IS__CGSCC____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] [[MRV]], i32 22, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] [[MRV1]]
; IS__CGSCC____: F:
; IS__CGSCC____-NEXT: [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
; IS__CGSCC____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] %mrv3
; IS__CGSCC____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] [[MRV2]], i32 23, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] [[MRV3]]
;
br i1 %Q, label %T, label %F

Expand All @@ -55,23 +55,23 @@ define internal %0 @bar(i1 %Q) {
; IS__TUNIT____-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
; IS__TUNIT____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT____: T:
; IS__TUNIT____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] %B
; IS__TUNIT____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] [[A]], i32 22, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] [[B]]
; IS__TUNIT____: F:
; IS__TUNIT____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] %C
; IS__TUNIT____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] [[A]], i32 23, 1
; IS__TUNIT____-NEXT: ret [[TMP0]] [[C]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
; IS__CGSCC____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC____: T:
; IS__CGSCC____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] %B
; IS__CGSCC____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] [[A]], i32 22, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] [[B]]
; IS__CGSCC____: F:
; IS__CGSCC____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] %C
; IS__CGSCC____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] [[A]], i32 23, 1
; IS__CGSCC____-NEXT: ret [[TMP0]] [[C]]
;
%A = insertvalue %0 undef, i32 21, 0
br i1 %Q, label %T, label %F
Expand All @@ -90,13 +90,13 @@ define %0 @caller(i1 %Q) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
; IS__TUNIT____-NEXT: ret [[TMP0]] %X
; IS__TUNIT____-NEXT: ret [[TMP0]] [[X]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
; IS__CGSCC____-NEXT: ret [[TMP0]] %X
; IS__CGSCC____-NEXT: ret [[TMP0]] [[X]]
;
%X = call %0 @foo(i1 %Q)
%A = extractvalue %0 %X, 0
Expand All @@ -115,11 +115,11 @@ define i32 @caller2(i1 %Q) {
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2
; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
; IS__TUNIT____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] %X, 0
; IS__TUNIT____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] %X, 1
; IS__TUNIT____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0
; IS__TUNIT____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1
; IS__TUNIT____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
; IS__TUNIT____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] %Y, 0
; IS__TUNIT____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
; IS__TUNIT____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0
; IS__TUNIT____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1
; IS__TUNIT____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
; IS__TUNIT____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]]
Expand All @@ -129,11 +129,11 @@ define i32 @caller2(i1 %Q) {
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2
; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
; IS__CGSCC____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] %X, 0
; IS__CGSCC____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] %X, 1
; IS__CGSCC____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0
; IS__CGSCC____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1
; IS__CGSCC____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
; IS__CGSCC____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] %Y, 0
; IS__CGSCC____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
; IS__CGSCC____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0
; IS__CGSCC____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1
; IS__CGSCC____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
; IS__CGSCC____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
; IS__CGSCC____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]]
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/Transforms/Attributor/dereferenceable-1.ll
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range)
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_fill_range
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, [[RNG0:!range !.*]]
; IS__TUNIT_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__TUNIT_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__TUNIT_OPM-NEXT: ret void
Expand All @@ -667,7 +667,7 @@ define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range)
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_fill_range
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, [[RNG0:!range !.*]]
; IS__TUNIT_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__TUNIT_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__TUNIT_NPM-NEXT: ret void
Expand All @@ -676,7 +676,7 @@ define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range)
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_fill_range
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, [[RNG0:!range !.*]]
; IS__CGSCC_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__CGSCC_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__CGSCC_OPM-NEXT: ret void
Expand All @@ -685,7 +685,7 @@ define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range)
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_fill_range
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, [[RNG0:!range !.*]]
; IS__CGSCC_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__CGSCC_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
; IS__CGSCC_NPM-NEXT: ret void
Expand Down Expand Up @@ -960,19 +960,19 @@ define void @nonnull_assume_pos(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) {
;
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]])
; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 true) #6 [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR6:#.*]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS__TUNIT_OPM-NEXT: call void @unknown()
; IS__TUNIT_OPM-NEXT: ret void
;
; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
; IS________NPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]])
; IS________NPM-NEXT: call void @llvm.assume(i1 true) #7 [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS________NPM-NEXT: call void @llvm.assume(i1 true) [[ATTR7:#.*]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS________NPM-NEXT: call void @unknown()
; IS________NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull readnone [[ARG3:%.*]], i8* nocapture nofree readnone dereferenceable_or_null(42) [[ARG4:%.*]])
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #8 [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR8:#.*]] [ "nonnull"(i8* [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8* [[ARG1]], i64 2), "dereferenceable"(i8* [[ARG1]], i64 101), "dereferenceable_or_null"(i8* [[ARG2]], i64 31), "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
; IS__CGSCC_OPM-NEXT: call void @unknown()
; IS__CGSCC_OPM-NEXT: ret void
;
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/Transforms/Attributor/liveness.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1570,7 +1570,8 @@ live_with_dead_entry:

define void @live_with_dead_entry_lp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@live_with_dead_entry_lp() #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
; CHECK-LABEL: define {{[^@]+}}@live_with_dead_entry_lp
; CHECK-SAME: () [[ATTR2:#.*]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
; CHECK-NEXT: entry:
; CHECK-NEXT: invoke void @blowup()
; CHECK-NEXT: to label [[LIVE_WITH_DEAD_ENTRY_DEAD:%.*]] unwind label [[LP1:%.*]]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/nocapture-1.ll
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ declare void @throw_if_bit_set(i8*, i8) readonly
define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@c6
; CHECK-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #4 personality i32 (...)* @__gxx_personality_v0
; CHECK-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) [[ATTR4:#.*]] personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]])
; CHECK-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
; CHECK: ret0:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/nofree.ll
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ define void @nonnull_assume_pos(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4) {
;
; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos
; CHECK-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]])
; CHECK-NEXT: call void @llvm.assume(i1 true) #11 [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [[ATTR11:#.*]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
; CHECK-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]])
; CHECK-NEXT: ret void
;
Expand Down
60 changes: 23 additions & 37 deletions llvm/test/Transforms/Attributor/nonnull.ll
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@ define i8* @test2A(i1 %c, i8* %ret) {
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]])
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; NOT_CGSCC_OPM: A:
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[RET]]) ]
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR11:#.*]] [ "nonnull"(i8* [[RET]]) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
; NOT_CGSCC_OPM: B:
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[RET]]) ]
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR11]] [ "nonnull"(i8* [[RET]]) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
;
; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; IS__CGSCC_OPM: A:
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "nonnull"(i8* [[RET]]) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR12:#.*]] [ "nonnull"(i8* [[RET]]) ]
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
; IS__CGSCC_OPM: B:
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "nonnull"(i8* [[RET]]) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR12]] [ "nonnull"(i8* [[RET]]) ]
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
;
br i1 %c, label %A, label %B
Expand All @@ -75,21 +75,21 @@ define i8* @test2B(i1 %c, i8* %ret) {
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]])
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; NOT_CGSCC_OPM: A:
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "dereferenceable"(i8* [[RET]], i32 4) ]
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR11]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
; NOT_CGSCC_OPM: B:
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "dereferenceable"(i8* [[RET]], i32 4) ]
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR11]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
;
; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; IS__CGSCC_OPM: A:
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "dereferenceable"(i8* [[RET]], i32 4) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
; IS__CGSCC_OPM: B:
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "dereferenceable"(i8* [[RET]], i32 4) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
; IS__CGSCC_OPM-NEXT: ret i8* [[RET]]
;
br i1 %c, label %A, label %B
Expand Down Expand Up @@ -794,33 +794,19 @@ define i8 @parent7(i8* %a) {
declare i32 @esfp(...)

define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
; NOT_CGSCC_OPM: Function Attrs: nounwind
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #4 personality i8* bitcast (i32 (...)* @esfp to i8*)
; NOT_CGSCC_OPM-NEXT: entry:
; NOT_CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
; NOT_CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; NOT_CGSCC_OPM: cont:
; NOT_CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
; NOT_CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
; NOT_CGSCC_OPM: exc:
; NOT_CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
; NOT_CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
; NOT_CGSCC_OPM-NEXT: unreachable
;
; IS__CGSCC_OPM: Function Attrs: nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #5 personality i8* bitcast (i32 (...)* @esfp to i8*)
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
; IS__CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; IS__CGSCC_OPM: cont:
; IS__CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
; IS__CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
; IS__CGSCC_OPM: exc:
; IS__CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
; IS__CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
; IS__CGSCC_OPM-NEXT: unreachable
; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@parent8
; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) [[ATTR4:#.*]] personality i8* bitcast (i32 (...)* @esfp to i8*)
; CHECK-NEXT: entry:
; CHECK-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; CHECK: cont:
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
; CHECK: exc:
; CHECK-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: filter [0 x i8*] zeroinitializer
; CHECK-NEXT: unreachable
;

entry:
Expand Down Expand Up @@ -1323,14 +1309,14 @@ define void @nonnull_assume_pos(i8* %arg) {
;
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[ARG]]) ]
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR11]] [ "nonnull"(i8* [[ARG]]) ]
; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
; NOT_CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [ "nonnull"(i8* [[ARG]]) ]
; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) [[ATTR12]] [ "nonnull"(i8* [[ARG]]) ]
; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
; IS__CGSCC_OPM-NEXT: ret void
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/Transforms/Attributor/potential.ll
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ define internal i32 @call_with_two_values(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@call_with_two_values
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 [[C]]) #0, !range !0
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 [[C]]) [[ATTR0:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT____-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]]
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) #0, !range !0
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) [[ATTR0]], [[RNG0]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
; IS__TUNIT____-NEXT: ret i32 [[RET]]
;
Expand All @@ -106,8 +106,8 @@ define i32 @potential_test2(i1 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test2
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 1) #0, !range !1
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 -1) #1, !range !1
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 1) [[ATTR0]], [[RNG1:!range !.*]]
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 -1) [[ATTR1:#.*]], [[RNG1]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
; IS__TUNIT____-NEXT: ret i32 [[RET]]
;
Expand Down Expand Up @@ -188,10 +188,10 @@ define i32 @potential_test3() {
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test3()
; IS__TUNIT_NPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 0) #0, !range !0
; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #0, !range !0
; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 1) #0, !range !0
; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #0, !range !0
; IS__TUNIT_NPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 0) [[ATTR0:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR0]], [[RNG0]]
; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 1) [[ATTR0]], [[RNG0]]
; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR0]], [[RNG0]]
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET]]
;
Expand Down Expand Up @@ -227,7 +227,7 @@ define i32 @potential_test4(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test4
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #0, !range !2
; IS__TUNIT____-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]]
; IS__TUNIT____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2
; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32
; IS__TUNIT____-NEXT: ret i32 [[RET]]
Expand All @@ -250,8 +250,8 @@ define i32 @potential_test5(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test5
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #0, !range !2
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) #0, !range !3
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) [[ATTR0]], [[RNG3:!range !.*]]
; IS__TUNIT____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32
; IS__TUNIT____-NEXT: ret i32 [[RET]]
Expand All @@ -276,7 +276,7 @@ define i1 @potential_test6(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test6
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #0, !range !2
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3
; IS__TUNIT____-NEXT: ret i1 [[RET]]
;
Expand All @@ -296,8 +296,8 @@ define i1 @potential_test7(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test7
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #0, !range !2
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #0, !range !4
; IS__TUNIT____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR0]], [[RNG2]]
; IS__TUNIT____-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG4:!range !.*]]
; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]
; IS__TUNIT____-NEXT: ret i1 [[RET]]
;
Expand Down
42 changes: 21 additions & 21 deletions llvm/test/Transforms/Attributor/range.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ define i32 @test0(i32* %p) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test0
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, [[RNG0:!range !.*]]
; IS__TUNIT____-NEXT: ret i32 [[A]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, [[RNG0:!range !.*]]
; IS__CGSCC____-NEXT: ret i32 [[A]]
;
%a = load i32, i32* %p, !range !0
Expand All @@ -27,13 +27,13 @@ define i32 @test0-range-check(i32* %p) {
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-range-check
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR3:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-range-check
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR2:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
Expand Down Expand Up @@ -62,7 +62,7 @@ define void @test0-icmp-check(i32* %p){
; ret = [0, 10)
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-icmp-check
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR3]], [[RNG0]]
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
Expand Down Expand Up @@ -109,7 +109,7 @@ define void @test0-icmp-check(i32* %p){
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-icmp-check
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR2]], [[RNG0]]
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
Expand Down Expand Up @@ -309,15 +309,15 @@ define i32 @test1(i32* %p) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
; IS__TUNIT____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, [[RNG1:!range !.*]]
; IS__TUNIT____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
; IS__TUNIT____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
; IS__TUNIT____-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
; IS__CGSCC____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, [[RNG1:!range !.*]]
; IS__CGSCC____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
; IS__CGSCC____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
; IS__CGSCC____-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
Expand All @@ -333,14 +333,14 @@ define i1 @test1-check(i32* %p) {
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1-check
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !2
; IS__TUNIT_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR3]], [[RNG2:!range !.*]]
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
;
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1-check
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !2
; IS__TUNIT_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR2]], [[RNG2:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
;
Expand Down Expand Up @@ -718,7 +718,7 @@ define dso_local i32 @test4-g2(i32 %u) {
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #1, !range !3
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR1:#.*]], [[RNG3:!range !.*]]
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
Expand All @@ -736,12 +736,12 @@ entry:
define dso_local i32 @test-5() {
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-5()
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !3
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), [[RNG3:!range !.*]]
; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-5()
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !4
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), [[RNG4:!range !.*]]
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
;
; IS__CGSCC____-LABEL: define {{[^@]+}}@test-5()
Expand Down Expand Up @@ -1216,8 +1216,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee_range_2
; IS__TUNIT_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !4
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #2, !range !4
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR2:#.*]], [[RNG4:!range !.*]]
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR2]], [[RNG4]]
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
Expand All @@ -1227,8 +1227,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_range_2
; IS__TUNIT_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #1, !range !5
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #1, !range !5
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR1]], [[RNG5:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR1]], [[RNG5]]
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
Expand Down Expand Up @@ -1360,10 +1360,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_OPM: t:
; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 [[C]]) #2, !range !3
; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 [[C]]) [[ATTR2]], [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_OPM: f:
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) #2, !range !3
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR2]], [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
Expand All @@ -1372,10 +1372,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_NPM: t:
; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true) #1, !range !4
; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true) [[ATTR1]], [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_NPM: f:
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) #1, !range !4
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR1]], [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET2]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Transforms/Attributor/value-simplify.ll
Original file line number Diff line number Diff line change
Expand Up @@ -363,25 +363,25 @@ define i32* @complicated_args_preallocated() {
; IS__TUNIT_OPM: Function Attrs: nounwind
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #5 [ "preallocated"(token [[C]]) ]
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) [[ATTR5:#.*]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]]
;
; IS__TUNIT_NPM: Function Attrs: nounwind
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #4 [ "preallocated"(token [[C]]) ]
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) [[ATTR4:#.*]] [ "preallocated"(token [[C]]) ]
; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC_OPM: Function Attrs: nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #6 [ "preallocated"(token [[C]]) ]
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) [[ATTR6:#.*]] [ "preallocated"(token [[C]]) ]
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
;
; IS__CGSCC_NPM: Function Attrs: nounwind
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #5 [ "preallocated"(token [[C]]) ]
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) [[ATTR5:#.*]] [ "preallocated"(token [[C]]) ]
; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]]
;
%c = call token @llvm.call.preallocated.setup(i32 1)
Expand Down
32 changes: 11 additions & 21 deletions llvm/test/Transforms/Attributor/willreturn.ll
Original file line number Diff line number Diff line change
Expand Up @@ -459,27 +459,17 @@ label2:
declare i1 @maybe_raise_exception() #1 willreturn

define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT____: Function Attrs: nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@invoke_test() #12 personality i32 (...)* @__gxx_personality_v0
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception()
; IS__TUNIT____-NEXT: to label [[N:%.*]] unwind label [[F:%.*]]
; IS__TUNIT____: N:
; IS__TUNIT____-NEXT: ret void
; IS__TUNIT____: F:
; IS__TUNIT____-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 }
; IS__TUNIT____-NEXT: catch i8* null
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@invoke_test() #14 personality i32 (...)* @__gxx_personality_v0
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception()
; IS__CGSCC____-NEXT: to label [[N:%.*]] unwind label [[F:%.*]]
; IS__CGSCC____: N:
; IS__CGSCC____-NEXT: ret void
; IS__CGSCC____: F:
; IS__CGSCC____-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 }
; IS__CGSCC____-NEXT: catch i8* null
; IS__CGSCC____-NEXT: ret void
; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@invoke_test
; CHECK-SAME: () [[ATTR14:#.*]] personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception()
; CHECK-NEXT: to label [[N:%.*]] unwind label [[F:%.*]]
; CHECK: N:
; CHECK-NEXT: ret void
; CHECK: F:
; CHECK-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: catch i8* null
; CHECK-NEXT: ret void
;
invoke i1 @maybe_raise_exception()
to label %N unwind label %F
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
; IS__TUNIT____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #0
; IS__TUNIT____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
; IS__TUNIT____-NEXT: ret i32* [[ARRAYIDX]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #0
; IS__CGSCC____-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
; IS__CGSCC____-NEXT: ret i32* [[ARRAYIDX]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) #0
; CHECK-SAME: (%struct.ST* nofree readnone [[S:%.*]]) [[ATTR0:#.*]]
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
; CHECK-NEXT: ret i32* [[ARRAYIDX]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ declare void @foo()

define internal void @bar() {
; CHECK-LABEL: @bar(
; CHECK-NEXT: call void @foo() #0
; CHECK-NEXT: call void @foo() [[ATTR0:#.*]]
; CHECK-NEXT: ret void
;
call void @foo() readnone
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
; Just run it through opt, no passes needed.
; RUN: opt < %s -S | FileCheck %s

; ModuleID = 'various_ir_values.c'
source_filename = "various_ir_values.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind uwtable
define dso_local void @foo(i32* %A) #0 !dbg !7 {
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !13, metadata !DIExpression()), !dbg !20
%0 = bitcast i32* %i to i8*, !dbg !21
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !21
call void @llvm.dbg.declare(metadata i32* %i, metadata !14, metadata !DIExpression()), !dbg !22
store i32 0, i32* %i, align 4, !dbg !22, !tbaa !23
br label %for.cond, !dbg !21

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !25, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !27, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !28, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !29
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !30

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !31
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !31
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !32, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !33, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !32
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !32
store i32 0, i32* %arrayidx, align 4, !dbg !34, !tbaa !23
br label %for.inc, !dbg !32

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !35, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !35
store i32 %inc, i32* %i, align 4, !dbg !35, !tbaa !23
br label %for.cond, !dbg !31, !llvm.loop !36

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !38
}

; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: nounwind uwtable
define dso_local void @bar(i32* %A) #0 !dbg !39 {
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !41, metadata !DIExpression()), !dbg !44
%0 = bitcast i32* %i to i8*, !dbg !45
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !45
call void @llvm.dbg.declare(metadata i32* %i, metadata !42, metadata !DIExpression()), !dbg !46
store i32 0, i32* %i, align 4, !dbg !46, !tbaa !23
br label %for.cond, !dbg !45

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !47, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !49, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !50, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !51
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !52

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !53
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !53
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !54, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !55, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !54
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !54
store i32 0, i32* %arrayidx, align 4, !dbg !56, !tbaa !23
br label %for.inc, !dbg !54

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !57, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !57
store i32 %inc, i32* %i, align 4, !dbg !57, !tbaa !23
br label %for.cond, !dbg !53, !llvm.loop !58

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !60
}

attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable willreturn }
attributes #2 = { argmemonly nounwind willreturn }
attributes #3 = { nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
!8 = !DISubroutineType(types: !9)
!9 = !{null, !10}
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!12 = !{!13, !14}
!13 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
!16 = !{!17, !17, i64 0}
!17 = !{!"any pointer", !18, i64 0}
!18 = !{!"omnipotent char", !19, i64 0}
!19 = !{!"Simple C/C++ TBAA"}
!20 = !DILocation(line: 1, column: 15, scope: !7)
!21 = !DILocation(line: 3, column: 8, scope: !15)
!22 = !DILocation(line: 3, column: 12, scope: !15)
!23 = !{!24, !24, i64 0}
!24 = !{!"int", !18, i64 0}
!25 = !DILocation(line: 3, column: 19, scope: !26)
!26 = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
!27 = !DILocation(line: 3, column: 24, scope: !26)
!28 = !DILocation(line: 3, column: 23, scope: !26)
!29 = !DILocation(line: 3, column: 21, scope: !26)
!30 = !DILocation(line: 3, column: 3, scope: !15)
!31 = !DILocation(line: 3, column: 3, scope: !26)
!32 = !DILocation(line: 4, column: 5, scope: !26)
!33 = !DILocation(line: 4, column: 7, scope: !26)
!34 = !DILocation(line: 4, column: 10, scope: !26)
!35 = !DILocation(line: 3, column: 27, scope: !26)
!36 = distinct !{!36, !30, !37}
!37 = !DILocation(line: 4, column: 12, scope: !15)
!38 = !DILocation(line: 5, column: 1, scope: !7)
!39 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40)
!40 = !{!41, !42}
!41 = !DILocalVariable(name: "A", arg: 1, scope: !39, file: !1, line: 7, type: !10)
!42 = !DILocalVariable(name: "i", scope: !43, file: !1, line: 9, type: !11)
!43 = distinct !DILexicalBlock(scope: !39, file: !1, line: 9, column: 3)
!44 = !DILocation(line: 7, column: 15, scope: !39)
!45 = !DILocation(line: 9, column: 8, scope: !43)
!46 = !DILocation(line: 9, column: 12, scope: !43)
!47 = !DILocation(line: 9, column: 19, scope: !48)
!48 = distinct !DILexicalBlock(scope: !43, file: !1, line: 9, column: 3)
!49 = !DILocation(line: 9, column: 24, scope: !48)
!50 = !DILocation(line: 9, column: 23, scope: !48)
!51 = !DILocation(line: 9, column: 21, scope: !48)
!52 = !DILocation(line: 9, column: 3, scope: !43)
!53 = !DILocation(line: 9, column: 3, scope: !48)
!54 = !DILocation(line: 10, column: 5, scope: !48)
!55 = !DILocation(line: 10, column: 7, scope: !48)
!56 = !DILocation(line: 10, column: 10, scope: !48)
!57 = !DILocation(line: 9, column: 27, scope: !48)
!58 = distinct !{!58, !52, !59}
!59 = !DILocation(line: 10, column: 12, scope: !43)
!60 = !DILocation(line: 11, column: 1, scope: !39)
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Just run it through opt, no passes needed.
; RUN: opt < %s -S | FileCheck %s

; ModuleID = 'various_ir_values.c'
source_filename = "various_ir_values.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind uwtable
define dso_local void @foo(i32* %A) #0 !dbg !7 {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, [[TBAA16:!tbaa !.*]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20:!dbg !.*]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG21:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3:#.*]], [[DBG21]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], [[META14:metadata !.*]], metadata !DIExpression()), [[DBG22:!dbg !.*]]
; CHECK-NEXT: store i32 0, i32* [[I]], align 4, [[DBG22]], [[TBAA23:!tbaa !.*]]
; CHECK-NEXT: br label [[FOR_COND:%.*]], [[DBG21]]
; CHECK: for.cond:
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG25:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG27:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG28:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG29:!dbg !.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG30:!dbg !.*]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG31:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG31]]
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG32:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG33:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG32]]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG32]]
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG34:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_INC:%.*]], [[DBG32]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG35:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG35]]
; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4, [[DBG35]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND]], [[DBG31]], [[LOOP36:!llvm.loop !.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void, [[DBG38:!dbg !.*]]
;
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !13, metadata !DIExpression()), !dbg !20
%0 = bitcast i32* %i to i8*, !dbg !21
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !21
call void @llvm.dbg.declare(metadata i32* %i, metadata !14, metadata !DIExpression()), !dbg !22
store i32 0, i32* %i, align 4, !dbg !22, !tbaa !23
br label %for.cond, !dbg !21

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !25, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !27, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !28, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !29
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !30

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !31
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !31
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !32, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !33, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !32
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !32
store i32 0, i32* %arrayidx, align 4, !dbg !34, !tbaa !23
br label %for.inc, !dbg !32

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !35, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !35
store i32 %inc, i32* %i, align 4, !dbg !35, !tbaa !23
br label %for.cond, !dbg !31, !llvm.loop !36

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !38
}

; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: nounwind uwtable
define dso_local void @bar(i32* %A) #0 !dbg !39 {
; CHECK-LABEL: @bar(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32* [[A:%.*]], i32** [[A_ADDR]], align 8, [[TBAA16]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META41:metadata !.*]], metadata !DIExpression()), [[DBG44:!dbg !.*]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG45:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3]], [[DBG45]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG46:!dbg !.*]]
; CHECK-NEXT: store i32 0, i32* [[I]], align 4, [[DBG46]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND:%.*]], [[DBG45]]
; CHECK: for.cond:
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG47:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG49:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG50:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG51:!dbg !.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG52:!dbg !.*]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG53:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG53]]
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG54:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG55:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG54]]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG54]]
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG56:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_INC:%.*]], [[DBG54]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG57:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG57]]
; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4, [[DBG57]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND]], [[DBG53]], [[LOOP58:!llvm.loop !.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void, [[DBG60:!dbg !.*]]
;
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !41, metadata !DIExpression()), !dbg !44
%0 = bitcast i32* %i to i8*, !dbg !45
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !45
call void @llvm.dbg.declare(metadata i32* %i, metadata !42, metadata !DIExpression()), !dbg !46
store i32 0, i32* %i, align 4, !dbg !46, !tbaa !23
br label %for.cond, !dbg !45

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !47, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !49, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !50, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !51
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !52

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !53
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !53
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !54, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !55, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !54
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !54
store i32 0, i32* %arrayidx, align 4, !dbg !56, !tbaa !23
br label %for.inc, !dbg !54

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !57, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !57
store i32 %inc, i32* %i, align 4, !dbg !57, !tbaa !23
br label %for.cond, !dbg !53, !llvm.loop !58

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !60
}

attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable willreturn }
attributes #2 = { argmemonly nounwind willreturn }
attributes #3 = { nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
!8 = !DISubroutineType(types: !9)
!9 = !{null, !10}
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!12 = !{!13, !14}
!13 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
!16 = !{!17, !17, i64 0}
!17 = !{!"any pointer", !18, i64 0}
!18 = !{!"omnipotent char", !19, i64 0}
!19 = !{!"Simple C/C++ TBAA"}
!20 = !DILocation(line: 1, column: 15, scope: !7)
!21 = !DILocation(line: 3, column: 8, scope: !15)
!22 = !DILocation(line: 3, column: 12, scope: !15)
!23 = !{!24, !24, i64 0}
!24 = !{!"int", !18, i64 0}
!25 = !DILocation(line: 3, column: 19, scope: !26)
!26 = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
!27 = !DILocation(line: 3, column: 24, scope: !26)
!28 = !DILocation(line: 3, column: 23, scope: !26)
!29 = !DILocation(line: 3, column: 21, scope: !26)
!30 = !DILocation(line: 3, column: 3, scope: !15)
!31 = !DILocation(line: 3, column: 3, scope: !26)
!32 = !DILocation(line: 4, column: 5, scope: !26)
!33 = !DILocation(line: 4, column: 7, scope: !26)
!34 = !DILocation(line: 4, column: 10, scope: !26)
!35 = !DILocation(line: 3, column: 27, scope: !26)
!36 = distinct !{!36, !30, !37}
!37 = !DILocation(line: 4, column: 12, scope: !15)
!38 = !DILocation(line: 5, column: 1, scope: !7)
!39 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40)
!40 = !{!41, !42}
!41 = !DILocalVariable(name: "A", arg: 1, scope: !39, file: !1, line: 7, type: !10)
!42 = !DILocalVariable(name: "i", scope: !43, file: !1, line: 9, type: !11)
!43 = distinct !DILexicalBlock(scope: !39, file: !1, line: 9, column: 3)
!44 = !DILocation(line: 7, column: 15, scope: !39)
!45 = !DILocation(line: 9, column: 8, scope: !43)
!46 = !DILocation(line: 9, column: 12, scope: !43)
!47 = !DILocation(line: 9, column: 19, scope: !48)
!48 = distinct !DILexicalBlock(scope: !43, file: !1, line: 9, column: 3)
!49 = !DILocation(line: 9, column: 24, scope: !48)
!50 = !DILocation(line: 9, column: 23, scope: !48)
!51 = !DILocation(line: 9, column: 21, scope: !48)
!52 = !DILocation(line: 9, column: 3, scope: !43)
!53 = !DILocation(line: 9, column: 3, scope: !48)
!54 = !DILocation(line: 10, column: 5, scope: !48)
!55 = !DILocation(line: 10, column: 7, scope: !48)
!56 = !DILocation(line: 10, column: 10, scope: !48)
!57 = !DILocation(line: 9, column: 27, scope: !48)
!58 = distinct !{!58, !52, !59}
!59 = !DILocation(line: 10, column: 12, scope: !43)
!60 = !DILocation(line: 11, column: 1, scope: !39)
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; Just run it through opt, no passes needed.
; RUN: opt < %s -S | FileCheck %s

; ModuleID = 'various_ir_values.c'
source_filename = "various_ir_values.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind uwtable
define dso_local void @foo(i32* %A) #0 !dbg !7 {
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: (i32* [[A:%.*]]) [[ATTR0:#.*]] [[DBG7:!dbg !.*]]
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8, [[TBAA16:!tbaa !.*]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20:!dbg !.*]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG21:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3:#.*]], [[DBG21]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], [[META14:metadata !.*]], metadata !DIExpression()), [[DBG22:!dbg !.*]]
; CHECK-NEXT: store i32 0, i32* [[I]], align 4, [[DBG22]], [[TBAA23:!tbaa !.*]]
; CHECK-NEXT: br label [[FOR_COND:%.*]], [[DBG21]]
; CHECK: for.cond:
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG25:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG27:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG28:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG29:!dbg !.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG30:!dbg !.*]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG31:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG31]]
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG32:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG33:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG32]]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG32]]
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG34:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_INC:%.*]], [[DBG32]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG35:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG35]]
; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4, [[DBG35]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND]], [[DBG31]], [[LOOP36:!llvm.loop !.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void, [[DBG38:!dbg !.*]]
;
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !13, metadata !DIExpression()), !dbg !20
%0 = bitcast i32* %i to i8*, !dbg !21
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !21
call void @llvm.dbg.declare(metadata i32* %i, metadata !14, metadata !DIExpression()), !dbg !22
store i32 0, i32* %i, align 4, !dbg !22, !tbaa !23
br label %for.cond, !dbg !21

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !25, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !27, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !28, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !29
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !30

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !31
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !31
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !32, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !33, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !32
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !32
store i32 0, i32* %arrayidx, align 4, !dbg !34, !tbaa !23
br label %for.inc, !dbg !32

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !35, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !35
store i32 %inc, i32* %i, align 4, !dbg !35, !tbaa !23
br label %for.cond, !dbg !31, !llvm.loop !36

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !38
}

; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2

; Function Attrs: nounwind uwtable
define dso_local void @bar(i32* %A) #0 !dbg !39 {
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: (i32* [[A:%.*]]) [[ATTR0]] [[DBG39:!dbg !.*]]
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8, [[TBAA16]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], [[META41:metadata !.*]], metadata !DIExpression()), [[DBG44:!dbg !.*]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[I]] to i8*, [[DBG45:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) [[ATTR3]], [[DBG45]]
; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG46:!dbg !.*]]
; CHECK-NEXT: store i32 0, i32* [[I]], align 4, [[DBG46]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND:%.*]], [[DBG45]]
; CHECK: for.cond:
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4, [[DBG47:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG49:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, [[DBG50:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], [[TMP3]], [[DBG51:!dbg !.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], [[DBG52:!dbg !.*]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[I]] to i8*, [[DBG53:!dbg !.*]]
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP4]]) [[ATTR3]], [[DBG53]]
; CHECK-NEXT: br label [[FOR_END:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, [[DBG54:!dbg !.*]], [[TBAA16]]
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I]], align 4, [[DBG55:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP6]] to i64, [[DBG54]]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP5]], i64 [[IDXPROM]], [[DBG54]]
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 4, [[DBG56:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_INC:%.*]], [[DBG54]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4, [[DBG57:!dbg !.*]], [[TBAA23]]
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1, [[DBG57]]
; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4, [[DBG57]], [[TBAA23]]
; CHECK-NEXT: br label [[FOR_COND]], [[DBG53]], [[LOOP58:!llvm.loop !.*]]
; CHECK: for.end:
; CHECK-NEXT: ret void, [[DBG60:!dbg !.*]]
;
entry:
%A.addr = alloca i32*, align 8
%i = alloca i32, align 4
store i32* %A, i32** %A.addr, align 8, !tbaa !16
call void @llvm.dbg.declare(metadata i32** %A.addr, metadata !41, metadata !DIExpression()), !dbg !44
%0 = bitcast i32* %i to i8*, !dbg !45
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #3, !dbg !45
call void @llvm.dbg.declare(metadata i32* %i, metadata !42, metadata !DIExpression()), !dbg !46
store i32 0, i32* %i, align 4, !dbg !46, !tbaa !23
br label %for.cond, !dbg !45

for.cond: ; preds = %for.inc, %entry
%1 = load i32, i32* %i, align 4, !dbg !47, !tbaa !23
%2 = load i32*, i32** %A.addr, align 8, !dbg !49, !tbaa !16
%3 = load i32, i32* %2, align 4, !dbg !50, !tbaa !23
%cmp = icmp slt i32 %1, %3, !dbg !51
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !52

for.cond.cleanup: ; preds = %for.cond
%4 = bitcast i32* %i to i8*, !dbg !53
call void @llvm.lifetime.end.p0i8(i64 4, i8* %4) #3, !dbg !53
br label %for.end

for.body: ; preds = %for.cond
%5 = load i32*, i32** %A.addr, align 8, !dbg !54, !tbaa !16
%6 = load i32, i32* %i, align 4, !dbg !55, !tbaa !23
%idxprom = sext i32 %6 to i64, !dbg !54
%arrayidx = getelementptr inbounds i32, i32* %5, i64 %idxprom, !dbg !54
store i32 0, i32* %arrayidx, align 4, !dbg !56, !tbaa !23
br label %for.inc, !dbg !54

for.inc: ; preds = %for.body
%7 = load i32, i32* %i, align 4, !dbg !57, !tbaa !23
%inc = add nsw i32 %7, 1, !dbg !57
store i32 %inc, i32* %i, align 4, !dbg !57, !tbaa !23
br label %for.cond, !dbg !53, !llvm.loop !58

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !60
}

attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable willreturn }
attributes #2 = { argmemonly nounwind willreturn }
attributes #3 = { nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
!8 = !DISubroutineType(types: !9)
!9 = !{null, !10}
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!12 = !{!13, !14}
!13 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
!16 = !{!17, !17, i64 0}
!17 = !{!"any pointer", !18, i64 0}
!18 = !{!"omnipotent char", !19, i64 0}
!19 = !{!"Simple C/C++ TBAA"}
!20 = !DILocation(line: 1, column: 15, scope: !7)
!21 = !DILocation(line: 3, column: 8, scope: !15)
!22 = !DILocation(line: 3, column: 12, scope: !15)
!23 = !{!24, !24, i64 0}
!24 = !{!"int", !18, i64 0}
!25 = !DILocation(line: 3, column: 19, scope: !26)
!26 = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
!27 = !DILocation(line: 3, column: 24, scope: !26)
!28 = !DILocation(line: 3, column: 23, scope: !26)
!29 = !DILocation(line: 3, column: 21, scope: !26)
!30 = !DILocation(line: 3, column: 3, scope: !15)
!31 = !DILocation(line: 3, column: 3, scope: !26)
!32 = !DILocation(line: 4, column: 5, scope: !26)
!33 = !DILocation(line: 4, column: 7, scope: !26)
!34 = !DILocation(line: 4, column: 10, scope: !26)
!35 = !DILocation(line: 3, column: 27, scope: !26)
!36 = distinct !{!36, !30, !37}
!37 = !DILocation(line: 4, column: 12, scope: !15)
!38 = !DILocation(line: 5, column: 1, scope: !7)
!39 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40)
!40 = !{!41, !42}
!41 = !DILocalVariable(name: "A", arg: 1, scope: !39, file: !1, line: 7, type: !10)
!42 = !DILocalVariable(name: "i", scope: !43, file: !1, line: 9, type: !11)
!43 = distinct !DILexicalBlock(scope: !39, file: !1, line: 9, column: 3)
!44 = !DILocation(line: 7, column: 15, scope: !39)
!45 = !DILocation(line: 9, column: 8, scope: !43)
!46 = !DILocation(line: 9, column: 12, scope: !43)
!47 = !DILocation(line: 9, column: 19, scope: !48)
!48 = distinct !DILexicalBlock(scope: !43, file: !1, line: 9, column: 3)
!49 = !DILocation(line: 9, column: 24, scope: !48)
!50 = !DILocation(line: 9, column: 23, scope: !48)
!51 = !DILocation(line: 9, column: 21, scope: !48)
!52 = !DILocation(line: 9, column: 3, scope: !43)
!53 = !DILocation(line: 9, column: 3, scope: !48)
!54 = !DILocation(line: 10, column: 5, scope: !48)
!55 = !DILocation(line: 10, column: 7, scope: !48)
!56 = !DILocation(line: 10, column: 10, scope: !48)
!57 = !DILocation(line: 9, column: 27, scope: !48)
!58 = distinct !{!58, !52, !59}
!59 = !DILocation(line: 10, column: 12, scope: !43)
!60 = !DILocation(line: 11, column: 1, scope: !39)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Basic test checking that update_test_checks.py works correctly on various "IR value" kinds
# RUN: cp -f %S/Inputs/various_ir_values.ll %t.ll && %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/various_ir_values.ll.expected
## Check that running the script again does not change the result:
# RUN: %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/various_ir_values.ll.expected
## Also try the --function-signature flag
# RUN: %update_test_checks %t.ll --function-signature
# RUN: diff -u %t.ll %S/Inputs/various_ir_values.ll.funcsig.expected
## Verify that running without the --function-signature flag does not removes
## the -SAME: lines since the generated file will have --function-signature in
## an UTC_ARGS: comment in the first line (from the invocation above) which is
## added to the update invocation below.
# RUN: %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/various_ir_values.ll.funcsig.expected

3 changes: 2 additions & 1 deletion llvm/utils/UpdateTestChecks/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,5 @@ def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, pre
def add_asm_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
# Label format is based on ASM string.
check_label_format = '{} %s-LABEL: %s%s:'.format(comment_marker)
common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False)
global_vars_seen_dict = {}
common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False, global_vars_seen_dict)
146 changes: 109 additions & 37 deletions llvm/utils/UpdateTestChecks/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ def __init__(self, string, extra, args_and_sig, attrs):
def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs):
arg_names = set()
def drop_arg_names(match):
arg_names.add(match.group(2))
return match.group(1) + match.group(3)
arg_names.add(match.group(3))
return match.group(1) + match.group(match.lastindex)
def repl_arg_names(match):
if match.group(2) in arg_names:
return match.group(1) + match.group(3)
return match.group(1) + match.group(2) + match.group(3)
if match.group(3) in arg_names:
return match.group(1) + match.group(match.lastindex)
return match.group(1) + match.group(2) + match.group(match.lastindex)
if self.attrs != attrs:
return False
ans0 = IR_VALUE_RE.sub(drop_arg_names, self.args_and_sig)
Expand Down Expand Up @@ -297,49 +297,111 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too

SCRUB_IR_COMMENT_RE = re.compile(r'\s*;.*')

# Match things that look at identifiers, but only if they are followed by
# spaces, commas, paren, or end of the string
IR_VALUE_RE = re.compile(r'(\s+)%([\w.-]+?)([,\s\(\)]|\Z)')

NAMELESS_PREFIX = "TMP"
# TODO: We should also derive check lines for global, debug, loop declarations, etc..

class NamelessValue:
def __init__(self, check_prefix, ir_prefix, ir_regexp):
self.check_prefix = check_prefix
self.ir_prefix = ir_prefix
self.ir_regexp = ir_regexp

# Description of the different "unnamed" values we match in the IR, e.g.,
# (local) ssa values, (debug) metadata, etc.
nameless_values = [
NamelessValue(r'TMP', r'%', r'[\w.-]+?'),
NamelessValue(r'GLOB', r'@', r'[0-9]+?'),
NamelessValue(r'ATTR', r'#', r'[0-9]+?'),
NamelessValue(r'DBG', r'!dbg !', r'[0-9]+?'),
NamelessValue(r'TBAA', r'!tbaa !', r'[0-9]+?'),
NamelessValue(r'RNG', r'!range !', r'[0-9]+?'),
NamelessValue(r'LOOP', r'!llvm.loop !', r'[0-9]+?'),
NamelessValue(r'META', r'metadata !', r'[0-9]+?'),
]

# Build the regexp that matches an "IR value". This can be a local variable,
# argument, global, or metadata, anything that is "named". It is important that
# the PREFIX and SUFFIX below only contain a single group, if that changes
# other locations will need adjustment as well.
IR_VALUE_REGEXP_PREFIX = r'(\s+)'
IR_VALUE_REGEXP_STRING = r''
for nameless_value in nameless_values:
if IR_VALUE_REGEXP_STRING:
IR_VALUE_REGEXP_STRING += '|'
IR_VALUE_REGEXP_STRING += nameless_value.ir_prefix + r'(' + nameless_value.ir_regexp + r')'
IR_VALUE_REGEXP_SUFFIX = r'([,\s\(\)]|\Z)'
IR_VALUE_RE = re.compile(IR_VALUE_REGEXP_PREFIX + r'(' + IR_VALUE_REGEXP_STRING + r')' + IR_VALUE_REGEXP_SUFFIX)

# The entire match is group 0, the prefix has one group (=1), the entire
# IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
first_nameless_group_in_ir_value_match = 3

# Check a match for IR_VALUE_RE and inspect it to determine if it was a local
# value, %..., global @..., debug number !dbg !..., etc. See the PREFIXES above.
def get_idx_from_ir_value_match(match):
for i in range(first_nameless_group_in_ir_value_match, match.lastindex):
if match.group(i) is not None:
return i - first_nameless_group_in_ir_value_match
error("Unable to identify the kind of IR value from the match!")
return 0;

# See get_idx_from_ir_value_match
def get_name_from_ir_value_match(match):
return match.group(get_idx_from_ir_value_match(match) + first_nameless_group_in_ir_value_match)

# Return the nameless prefix we use for this kind or IR value, see also
# get_idx_from_ir_value_match
def get_nameless_check_prefix_from_ir_value_match(match):
return nameless_values[get_idx_from_ir_value_match(match)].check_prefix

# Return the IR prefix we use for this kind or IR value, e.g., % for locals,
# see also get_idx_from_ir_value_match
def get_ir_prefix_from_ir_value_match(match):
return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix

# Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'.
def is_local_ir_value_match(match):
return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix == '%'

# Create a FileCheck variable name based on an IR name.
def get_value_name(var):
def get_value_name(var, match):
if var.isdigit():
var = NAMELESS_PREFIX + var
var = get_nameless_check_prefix_from_ir_value_match(match) + var
var = var.replace('.', '_')
var = var.replace('-', '_')
return var.upper()


# Create a FileCheck variable from regex.
def get_value_definition(var):
return '[[' + get_value_name(var) + ':%.*]]'

def get_value_definition(var, match):
return '[[' + get_value_name(var, match) + ':' + get_ir_prefix_from_ir_value_match(match) + '.*]]'

# Use a FileCheck variable.
def get_value_use(var):
return '[[' + get_value_name(var) + ']]'
def get_value_use(var, match):
return '[[' + get_value_name(var, match) + ']]'

# Replace IR value defs and uses with FileCheck variables.
def genericize_check_lines(lines, is_analyze, vars_seen):
def genericize_check_lines(lines, is_analyze, vars_seen, global_vars_seen):
# This gets called for each match that occurs in
# a line. We transform variables we haven't seen
# into defs, and variables we have seen into uses.
def transform_line_vars(match):
var = match.group(2)
if NAMELESS_PREFIX.lower() in var.lower():
warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,))
if var in vars_seen:
rv = get_value_use(var)
pre = get_ir_prefix_from_ir_value_match(match)
var = get_name_from_ir_value_match(match)
for nameless_value in nameless_values:
if re.fullmatch(nameless_value.ir_prefix + r'[0-9]+?', var, re.IGNORECASE):
warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,))
if (pre, var) in vars_seen or (pre, var) in global_vars_seen:
rv = get_value_use(var, match)
else:
vars_seen.add(var)
rv = get_value_definition(var)
if is_local_ir_value_match(match):
vars_seen.add((pre, var))
else:
global_vars_seen.add((pre, var))
rv = get_value_definition(var, match)
# re.sub replaces the entire regex match
# with whatever you return, so we have
# to make sure to hand it back everything
# including the commas and spaces.
return match.group(1) + rv + match.group(3)
return match.group(1) + rv + match.group(match.lastindex)

lines_with_def = []

Expand All @@ -348,14 +410,18 @@ def transform_line_vars(match):
line = line.replace('%.', '%dot')
# Ignore any comments, since the check lines will too.
scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r'', line)
if is_analyze:
lines[i] = scrubbed_line
else:
lines[i] = IR_VALUE_RE.sub(transform_line_vars, scrubbed_line)
lines[i] = scrubbed_line
if not is_analyze:
# It can happen that two matches are back-to-back and for some reason sub
# will not replace both of them. For now we work around this by
# substituting until there is no more match.
changed = True
while changed:
(lines[i], changed) = IR_VALUE_RE.subn(transform_line_vars, lines[i], count=1)
return lines


def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze):
def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze, global_vars_seen_dict):
# prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well.
prefix_exclusions = set()
printed_prefixes = []
Expand Down Expand Up @@ -389,14 +455,18 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
if len(printed_prefixes) != 0:
output_lines.append(comment_marker)

if checkprefix not in global_vars_seen_dict:
global_vars_seen_dict[checkprefix] = set()
global_vars_seen = global_vars_seen_dict[checkprefix]

vars_seen = set()
printed_prefixes.append(checkprefix)
attrs = str(func_dict[checkprefix][func_name].attrs)
attrs = '' if attrs == 'None' else attrs
if attrs:
output_lines.append('%s %s: Function Attrs: %s' % (comment_marker, checkprefix, attrs))
args_and_sig = str(func_dict[checkprefix][func_name].args_and_sig)
args_and_sig = genericize_check_lines([args_and_sig], is_analyze, vars_seen)[0]
args_and_sig = genericize_check_lines([args_and_sig], is_analyze, vars_seen, global_vars_seen)[0]
if '[[' in args_and_sig:
output_lines.append(check_label_format % (checkprefix, func_name, ''))
output_lines.append('%s %s-SAME: %s' % (comment_marker, checkprefix, args_and_sig))
Expand All @@ -416,7 +486,7 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,

# For IR output, change all defs to FileCheck variables, so we're immune
# to variable naming fashions.
func_body = genericize_check_lines(func_body, is_analyze, vars_seen)
func_body = genericize_check_lines(func_body, is_analyze, vars_seen, global_vars_seen)

# This could be selectively enabled with an optional invocation argument.
# Disabled for now: better to check everything. Be safe rather than sorry.
Expand Down Expand Up @@ -453,16 +523,18 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
break

def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict,
func_name, preserve_names, function_sig):
func_name, preserve_names, function_sig, global_vars_seen_dict):
# Label format is based on IR string.
function_def_regex = 'define {{[^@]+}}' if function_sig else ''
check_label_format = '{} %s-LABEL: {}@%s%s'.format(comment_marker, function_def_regex)
add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
check_label_format, False, preserve_names)
check_label_format, False, preserve_names, global_vars_seen_dict)

def add_analyze_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
check_label_format = '{} %s-LABEL: \'%s%s\''.format(comment_marker)
add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, False, True)
global_vars_see_dict = {}
add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
check_label_format, False, True, global_vars_seen_dict)


def check_prefix(prefix):
Expand Down
3 changes: 2 additions & 1 deletion llvm/utils/update_cc_test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ def main():
for k, v in get_line2spell_and_mangled(ti.args, clang_args).items():
line2spell_and_mangled_list[k].append(v)

global_vars_seen_dict = {}
prefix_set = set([prefix for p in run_list for prefix in p[0]])
output_lines = []
for line_info in ti.iterlines(output_lines):
Expand Down Expand Up @@ -293,7 +294,7 @@ def main():
output_lines.append('//')
added.add(mangled)
common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
False, args.function_signature)
False, args.function_signature, global_vars_seen_dict)
if line.rstrip('\n') == '//':
include_line = False

Expand Down
4 changes: 3 additions & 1 deletion llvm/utils/update_test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def main():
# now, we just ignore all but the last.
prefix_list.append((check_prefixes, tool_cmd_args))

global_vars_seen_dict = {}
func_dict = {}
for prefixes, _ in prefix_list:
for prefix in prefixes:
Expand Down Expand Up @@ -134,7 +135,8 @@ def main():

# Print out the various check lines here.
common.add_ir_checks(output_lines, ';', prefix_list, func_dict,
func_name, args.preserve_names, args.function_signature)
func_name, args.preserve_names, args.function_signature,
global_vars_seen_dict)
is_in_function_start = False

if is_in_function:
Expand Down