[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
aeubanks wrote: for future reference, https://github.com/llvm/llvm-project/commit/3cd67eeca28ab1084d02b7976de1af4c4c8d37d5 fixes a miscompile that this patch uncovered https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
https://github.com/nikic closed https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
andjo403 wrote: Comment fixed and need help with merging. https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
@@ -1444,6 +1445,8 @@ static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase ) { Valid.addAttribute(Attribute::NonNull); if (CB.hasRetAttr(Attribute::Alignment)) Valid.addAlignmentAttr(CB.getRetAlign()); + if (CB.hasRetAttr(Attribute::Range)) +Valid.addRangeAttr(*CB.getRange()); andjo403 wrote: fixed https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/92666 >From 1bc922a6797555b0bf69b187224ba054978fb7ad Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 18 May 2024 19:42:03 +0200 Subject: [PATCH 1/2] [inline] Tests for clone return range attribute on the callsite into inlined call [NFC] --- .../Inline/ret_attr_align_and_noundef.ll | 73 +++ 1 file changed, 73 insertions(+) diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll index c038ffccf3e96..7e76401c0b4de 100644 --- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll +++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll @@ -5,10 +5,12 @@ declare ptr @foo() declare void @use.ptr(ptr) willreturn nounwind +declare void @use.val(i8) willreturn nounwind declare void @bar() declare void @baz() declare ptr @llvm.ptrmask.p0.i64(ptr, i64) declare i1 @val() +declare i8 @val8() define ptr @callee0123() { ; CHECK-LABEL: define ptr @callee0123() { @@ -337,3 +339,74 @@ define ptr @caller12_todo() { %r = call nonnull ptr @callee12() ret ptr %r } + +define i8 @callee13() { +; CHECK-LABEL: define i8 @callee13() { +; CHECK-NEXT:[[R:%.*]] = call i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call i8 @val8() + ret i8 %r +} + +define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-NEXT:[[R_I:%.*]] = call i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 10) i8 @callee13() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @callee14() { +; CHECK-LABEL: define i8 @callee14() { +; CHECK-NEXT:[[R:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call noundef i8 @val8() + ret i8 %r +} + +define i8 @caller14_fail_creates_ub() { +; CHECK-LABEL: define i8 @caller14_fail_creates_ub() { +; CHECK-NEXT:[[R_I:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 10) i8 @callee14() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @caller14_okay_is_ub_anyways() { +; CHECK-LABEL: define i8 @caller14_okay_is_ub_anyways() { +; CHECK-NEXT:[[R_I:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call noundef range(i8 0, 10) i8 @callee14() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @callee15() { +; CHECK-LABEL: define i8 @callee15() { +; CHECK-NEXT:[[R:%.*]] = call range(i8 5, 10) i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call range(i8 5, 10) i8 @val8() + ret i8 %r +} + +define i8 @caller15_okay_intersect_ranges() { +; CHECK-LABEL: define i8 @caller15_okay_intersect_ranges() { +; CHECK-NEXT:[[R_I:%.*]] = call range(i8 5, 10) i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 7) i8 @callee15() + call void @use.val(i8 %r) + ret i8 %r +} >From 4472fc7e3de2460bce3afb42e0c00ed13bf4980c Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 18 May 2024 19:44:31 +0200 Subject: [PATCH 2/2] [inline] Clone return range attribute on the callsite into inlined call --- clang/test/Headers/__clang_hip_math.hip | 6 +++--- llvm/lib/Transforms/Utils/InlineFunction.cpp| 13 - .../Transforms/Inline/ret_attr_align_and_noundef.ll | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 1271868a53b86..26da82843c512 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -231,7 +231,7 @@ extern "C" __device__ uint64_t test___make_mantissa(const char *p) { // CHECK-LABEL: @test_abs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i32 0, -2147483648) i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) // CHECK-NEXT:ret i32 [[TMP0]] // extern "C" __device__ int test_abs(int x) { @@ -240,7 +240,7 @@ extern "C" __device__ int test_abs(int x) { // CHECK-LABEL: @test_labs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i64 0, -9223372036854775808) i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) // CHECK-NEXT:ret i64 [[TMP0]] // extern "C" __device__ long test_labs(long x) { @@ -249,7 +249,7 @@ extern "C" __device__ long test_labs(long x) { // CHECK-LABEL: @test_llabs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +// CHECK-NEXT:
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
https://github.com/nikic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
https://github.com/nikic edited https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
@@ -1444,6 +1445,8 @@ static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase ) { Valid.addAttribute(Attribute::NonNull); if (CB.hasRetAttr(Attribute::Alignment)) Valid.addAlignmentAttr(CB.getRetAlign()); + if (CB.hasRetAttr(Attribute::Range)) +Valid.addRangeAttr(*CB.getRange()); nikic wrote: ```suggestion if (std::optional Range = CB.getRange()) Valid.addRangeAttr(Range); ``` https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
andjo403 wrote: It was the usage of exactIntersectWith in https://github.com/llvm/llvm-project/pull/91101 vs the intersectWith that I used that I wanted to sort out but think that we have conluded that it shall be intersectWith. so this it ready for review https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
andjo403 wrote: hmm noticed #91101 now looks like I need to coordinate with that PR https://github.com/llvm/llvm-project/pull/92666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Andreas Jonson (andjo403) Changes CC @goldsteinn @nikic --- Full diff: https://github.com/llvm/llvm-project/pull/92666.diff 3 Files Affected: - (modified) clang/test/Headers/__clang_hip_math.hip (+3-3) - (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+12-1) - (modified) llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll (+73) ``diff diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 1271868a53b86..26da82843c512 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -231,7 +231,7 @@ extern "C" __device__ uint64_t test___make_mantissa(const char *p) { // CHECK-LABEL: @test_abs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i32 0, -2147483648) i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) // CHECK-NEXT:ret i32 [[TMP0]] // extern "C" __device__ int test_abs(int x) { @@ -240,7 +240,7 @@ extern "C" __device__ int test_abs(int x) { // CHECK-LABEL: @test_labs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i64 0, -9223372036854775808) i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) // CHECK-NEXT:ret i64 [[TMP0]] // extern "C" __device__ long test_labs(long x) { @@ -249,7 +249,7 @@ extern "C" __device__ long test_labs(long x) { // CHECK-LABEL: @test_llabs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i64 0, -9223372036854775808) i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) // CHECK-NEXT:ret i64 [[TMP0]] // extern "C" __device__ long long test_llabs(long x) { diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 82daaedaa0e81..ccc66c9c5cf23 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -30,11 +30,12 @@ #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" -#include "llvm/IR/AttributeMask.h" #include "llvm/IR/Argument.h" +#include "llvm/IR/AttributeMask.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" @@ -1444,6 +1445,8 @@ static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase ) { Valid.addAttribute(Attribute::NonNull); if (CB.hasRetAttr(Attribute::Alignment)) Valid.addAlignmentAttr(CB.getRetAlign()); + if (CB.hasRetAttr(Attribute::Range)) +Valid.addRangeAttr(*CB.getRange()); return Valid; } @@ -1535,6 +1538,14 @@ static void AddReturnAttributes(CallBase , ValueToValueMapTy ) { if (ValidPG.getAlignment().valueOrOne() < AL.getRetAlignment().valueOrOne()) ValidPG.removeAttribute(Attribute::Alignment); if (ValidPG.hasAttributes()) { + Attribute CBRange = ValidPG.getAttribute(Attribute::Range); + if (CBRange.isValid()) { +Attribute NewRange = AL.getRetAttr(Attribute::Range); +if (NewRange.isValid()) { + ValidPG.addRangeAttr( + CBRange.getRange().intersectWith(NewRange.getRange())); +} + } // Three checks. // If the callsite has `noundef`, then a poison due to violating the // return attribute will create UB anyways so we can always propagate. diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll index c038ffccf3e96..f4cebf1fcb5da 100644 --- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll +++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll @@ -5,10 +5,12 @@ declare ptr @foo() declare void @use.ptr(ptr) willreturn nounwind +declare void @use.val(i8) willreturn nounwind declare void @bar() declare void @baz() declare ptr @llvm.ptrmask.p0.i64(ptr, i64) declare i1 @val() +declare i8 @val8() define ptr @callee0123() { ; CHECK-LABEL: define ptr @callee0123() { @@ -337,3 +339,74 @@ define ptr @caller12_todo() { %r = call nonnull ptr @callee12() ret ptr %r } + +define i8 @callee13() { +; CHECK-LABEL: define i8 @callee13() { +; CHECK-NEXT:[[R:%.*]] = call i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call i8 @val8() + ret i8 %r +} + +define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-NEXT:[[R_I:%.*]] = call range(i8 0, 10) i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]]
[clang] [llvm] [inline] Clone return range attribute on the callsite into inlined call (PR #92666)
https://github.com/andjo403 created https://github.com/llvm/llvm-project/pull/92666 CC @goldsteinn @nikic >From 6dd513a670e813a5e6745044bc69fdd7a7b7c4d9 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 18 May 2024 19:42:03 +0200 Subject: [PATCH 1/2] [inline] Tests for clone return range attribute on the callsite into inlined call [NFC] --- .../Inline/ret_attr_align_and_noundef.ll | 73 +++ 1 file changed, 73 insertions(+) diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll index c038ffccf3e96..7e76401c0b4de 100644 --- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll +++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll @@ -5,10 +5,12 @@ declare ptr @foo() declare void @use.ptr(ptr) willreturn nounwind +declare void @use.val(i8) willreturn nounwind declare void @bar() declare void @baz() declare ptr @llvm.ptrmask.p0.i64(ptr, i64) declare i1 @val() +declare i8 @val8() define ptr @callee0123() { ; CHECK-LABEL: define ptr @callee0123() { @@ -337,3 +339,74 @@ define ptr @caller12_todo() { %r = call nonnull ptr @callee12() ret ptr %r } + +define i8 @callee13() { +; CHECK-LABEL: define i8 @callee13() { +; CHECK-NEXT:[[R:%.*]] = call i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call i8 @val8() + ret i8 %r +} + +define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() { +; CHECK-NEXT:[[R_I:%.*]] = call i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 10) i8 @callee13() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @callee14() { +; CHECK-LABEL: define i8 @callee14() { +; CHECK-NEXT:[[R:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call noundef i8 @val8() + ret i8 %r +} + +define i8 @caller14_fail_creates_ub() { +; CHECK-LABEL: define i8 @caller14_fail_creates_ub() { +; CHECK-NEXT:[[R_I:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 10) i8 @callee14() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @caller14_okay_is_ub_anyways() { +; CHECK-LABEL: define i8 @caller14_okay_is_ub_anyways() { +; CHECK-NEXT:[[R_I:%.*]] = call noundef i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call noundef range(i8 0, 10) i8 @callee14() + call void @use.val(i8 %r) + ret i8 %r +} + +define i8 @callee15() { +; CHECK-LABEL: define i8 @callee15() { +; CHECK-NEXT:[[R:%.*]] = call range(i8 5, 10) i8 @val8() +; CHECK-NEXT:ret i8 [[R]] +; + %r = call range(i8 5, 10) i8 @val8() + ret i8 %r +} + +define i8 @caller15_okay_intersect_ranges() { +; CHECK-LABEL: define i8 @caller15_okay_intersect_ranges() { +; CHECK-NEXT:[[R_I:%.*]] = call range(i8 5, 10) i8 @val8() +; CHECK-NEXT:call void @use.val(i8 [[R_I]]) +; CHECK-NEXT:ret i8 [[R_I]] +; + %r = call range(i8 0, 7) i8 @callee15() + call void @use.val(i8 %r) + ret i8 %r +} >From 9a6ad2805ea6d02050e9ac16e4041ca3277e52a4 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 18 May 2024 19:44:31 +0200 Subject: [PATCH 2/2] [inline] Clone return range attribute on the callsite intoinlined call --- clang/test/Headers/__clang_hip_math.hip | 6 +++--- llvm/lib/Transforms/Utils/InlineFunction.cpp| 13 - .../Transforms/Inline/ret_attr_align_and_noundef.ll | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 1271868a53b86..26da82843c512 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -231,7 +231,7 @@ extern "C" __device__ uint64_t test___make_mantissa(const char *p) { // CHECK-LABEL: @test_abs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i32 0, -2147483648) i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true) // CHECK-NEXT:ret i32 [[TMP0]] // extern "C" __device__ int test_abs(int x) { @@ -240,7 +240,7 @@ extern "C" __device__ int test_abs(int x) { // CHECK-LABEL: @test_labs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef range(i64 0, -9223372036854775808) i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) // CHECK-NEXT:ret i64 [[TMP0]] // extern "C" __device__ long test_labs(long x) { @@ -249,7 +249,7 @@ extern "C" __device__ long test_labs(long x) { // CHECK-LABEL: @test_llabs( // CHECK-NEXT: entry: -// CHECK-NEXT:[[TMP0:%.*]] = tail call noundef i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true) +//