[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/135754 [ConstraintElim] Opimize abs based on known constraints update test >From af8e5662259fe323f403a48140443feb22e9ef63 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/2] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 31 +++-- .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6608d65f797c5..dca55cc48d91f 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1132,7 +1132,6 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: - // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // TODO: Check if it is possible to instead only added the min/max facts @@ -1140,11 +1139,11 @@ void State::addInfoFor(BasicBlock &BB) { if (isGuaranteedNotToBePoison(&I)) WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; +case Intrinsic::abs: case Intrinsic::usub_sat: WorkList.push_back( - FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); +FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1540,6 +1539,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1866,6 +1887,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
el-ev wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/135754?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#135754** https://app.graphite.dev/github/pr/llvm/llvm-project/135754?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> ๐ https://app.graphite.dev/github/pr/llvm/llvm-project/135754?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#135744** https://app.graphite.dev/github/pr/llvm/llvm-project/135744?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/135754 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp -- llvm/lib/Transforms/Scalar/ConstraintElimination.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index dca55cc48..9eedd701b 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1142,7 +1142,7 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::abs: case Intrinsic::usub_sat: WorkList.push_back( -FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); + FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); [[fallthrough]]; case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); `` https://github.com/llvm/llvm-project/pull/135754 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][NPM] Add isRequired to passes missing it (PR #134033)
https://github.com/optimisan edited https://github.com/llvm/llvm-project/pull/134033 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From af8e5662259fe323f403a48140443feb22e9ef63 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/3] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 31 +++-- .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6608d65f797c5..dca55cc48d91f 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1132,7 +1132,6 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: - // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // TODO: Check if it is possible to instead only added the min/max facts @@ -1140,11 +1139,11 @@ void State::addInfoFor(BasicBlock &BB) { if (isGuaranteedNotToBePoison(&I)) WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; +case Intrinsic::abs: case Intrinsic::usub_sat: WorkList.push_back( - FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); +FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1540,6 +1539,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1866,6 +1887,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precon
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
el-ev wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/135785?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#135785** https://app.graphite.dev/github/pr/llvm/llvm-project/135785?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> ๐ https://app.graphite.dev/github/pr/llvm/llvm-project/135785?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#135784** https://app.graphite.dev/github/pr/llvm/llvm-project/135784?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/135785 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: Iris (el-ev) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/135785.diff 2 Files Affected: - (modified) llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (+10) - (modified) llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll (+11-22) ``diff diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 7ebd91dbb8ce4..412e59b3e7683 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1123,6 +1123,7 @@ void State::addInfoFor(BasicBlock &BB) { // Enqueue overflow intrinsics for simplification. case Intrinsic::sadd_with_overflow: case Intrinsic::ssub_with_overflow: +case Intrinsic::usub_with_overflow: case Intrinsic::ucmp: case Intrinsic::scmp: WorkList.push_back( @@ -1785,6 +1786,15 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, Changed = replaceSubOverflowUses(II, A, B, ToRemove); break; } + case Intrinsic::usub_with_overflow: { +// usub overflows iff A < B +// TODO: If the operation is guaranteed to overflow, we could +// also apply some simplifications. +if (DoesConditionHold(CmpInst::ICMP_UGE, A, B, Info)) { + Changed = replaceSubOverflowUses(II, A, B, ToRemove); +} +break; + } } return Changed; diff --git a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll index 06bfd8269d97d..0a3c4eb00fd25 100644 --- a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll +++ b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll @@ -9,11 +9,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -41,11 +39,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -75,12 +71,11 @@ define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] ; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) ; CHECK-NEXT:call void @use_res({ i8, i1 } [[OP]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -111,11 +106,9 @@ define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { ; CHECK-NEXT:[[OR:%.*]] = or i1 [[C_2]], [[C_1]] ; CHECK-NEXT:br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-N
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
https://github.com/el-ev ready_for_review https://github.com/llvm/llvm-project/pull/135785 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/135785 None >From 2770fb23d36d28512c928c60cf5424e309fd73aa Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 20:20:45 +0800 Subject: [PATCH] [ConstraintElim] Simplify `usub_with_overflow` when A uge B --- .../Scalar/ConstraintElimination.cpp | 10 ++ .../usub-with-overflow.ll | 33 +++ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 7ebd91dbb8ce4..412e59b3e7683 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1123,6 +1123,7 @@ void State::addInfoFor(BasicBlock &BB) { // Enqueue overflow intrinsics for simplification. case Intrinsic::sadd_with_overflow: case Intrinsic::ssub_with_overflow: +case Intrinsic::usub_with_overflow: case Intrinsic::ucmp: case Intrinsic::scmp: WorkList.push_back( @@ -1785,6 +1786,15 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, Changed = replaceSubOverflowUses(II, A, B, ToRemove); break; } + case Intrinsic::usub_with_overflow: { +// usub overflows iff A < B +// TODO: If the operation is guaranteed to overflow, we could +// also apply some simplifications. +if (DoesConditionHold(CmpInst::ICMP_UGE, A, B, Info)) { + Changed = replaceSubOverflowUses(II, A, B, ToRemove); +} +break; + } } return Changed; diff --git a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll index 06bfd8269d97d..0a3c4eb00fd25 100644 --- a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll +++ b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll @@ -9,11 +9,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -41,11 +39,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -75,12 +71,11 @@ define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] ; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) ; CHECK-NEXT:call void @use_res({ i8, i1 } [[OP]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -111,11 +106,9 @@ define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { ; CHECK-NEXT:[[OR:%.*]] = or i1 [[C_2]], [[C_1]] ; CHECK-NEXT:br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[E
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From 370305c4926ec615ff1d0408afad145279a721fe Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 29 - .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6af5d2c1c0b7b..d544b5a19920d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1128,12 +1128,12 @@ void State::addInfoFor(BasicBlock &BB) { FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); break; // Enqueue the intrinsics to add extra info. +case Intrinsic::abs: case Intrinsic::umin: case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: case Intrinsic::usub_sat: -// TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // TODO: Check if it is possible to instead only added the min/max facts @@ -1141,7 +1141,6 @@ void State::addInfoFor(BasicBlock &BB) { if (!isGuaranteedNotToBePoison(&I)) break; [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1537,6 +1536,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1863,6 +1884,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 3 + call void @llvm.assume(i1 %precond) + %abs
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,113 @@ +//===- MCGOFFAttributes.h - Attributes of GOFF symbols ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Defines the various attribute collections defining GOFF symbols. +// +//===--===// + +#ifndef LLVM_MC_MCGOFFATTRIBUTES_H +#define LLVM_MC_MCGOFFATTRIBUTES_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/GOFF.h" + +namespace llvm { +namespace GOFF { +// An "External Symbol Definition" in the GOFF file has a type, and depending on +// the type a different subset of the fields is used. +// +// Unlike other formats, a 2 dimensional structure is used to define the +// location of data. For example, the equivalent of the ELF .text section is +// made up of a Section Definition (SD) and a class (Element Definition; ED). +// The name of the SD symbol depends on the application, while the class has the +// predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively. +// +// Data can be placed into this structure in 2 ways. First, the data (in a text +// record) can be associated with an ED symbol. To refer to data, a Label +// Definition (LD) is used to give an offset into the data a name. When binding, +// the whole data is pulled into the resulting executable, and the addresses +// given by the LD symbols are resolved. +// +// The alternative is to use a Part Definition (PR). In this case, the data (in +// a text record) is associated with the part. When binding, only the data of +// referenced PRs is pulled into the resulting binary. +// +// Both approaches are used, which means that the equivalent of a section in ELF +// results in 3 GOFF symbols, either SD/ED/LD or SD/ED/PR. Moreover, certain +// sections are fine with just defining SD/ED symbols. The SymbolMapper takes +// care of all those details. + +// Attributes for SD symbols. +struct SDAttr { + GOFF::ESDTaskingBehavior TaskingBehavior = GOFF::ESD_TA_Unspecified; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for ED symbols. +struct EDAttr { + bool IsReadOnly = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDAmode Amode; + GOFF::ESDRmode Rmode; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented; + GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; + GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; + GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; + GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; +}; + +// Attributes for LD symbols. +struct LDAttr { + bool IsRenamable = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for PR symbols. +struct PRAttr { + bool IsRenamable = false; + bool IsReadOnly = false; // Not documented. + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; + GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity = + GOFF::ESD_DSS_NoWarning; redstar wrote: Me too. I need to ask someone with more HLASM knowledge. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to svusmmla (PR #135634)
@@ -273,6 +273,34 @@ def UmmlaOp : ArmSVE_Op<"ummla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } +def UsmmlaOp : ArmSVE_Op<"usmmla", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { momchil-velikov wrote: It's inconsistent only if others were consistent with each other. I've updated some, but really with a lack of a policy (or automated process) it's rather futile to try to guess what one or another reviewer would like. https://github.com/llvm/llvm-project/pull/135634 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From 370305c4926ec615ff1d0408afad145279a721fe Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 29 - .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6af5d2c1c0b7b..d544b5a19920d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1128,12 +1128,12 @@ void State::addInfoFor(BasicBlock &BB) { FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); break; // Enqueue the intrinsics to add extra info. +case Intrinsic::abs: case Intrinsic::umin: case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: case Intrinsic::usub_sat: -// TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // TODO: Check if it is possible to instead only added the min/max facts @@ -1141,7 +1141,6 @@ void State::addInfoFor(BasicBlock &BB) { if (!isGuaranteedNotToBePoison(&I)) break; [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1537,6 +1536,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1863,6 +1884,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 3 + call void @llvm.assume(i1 %precond) + %abs
[llvm-branch-commits] [llvm] [LV] Disable epilogue vectorization for FindLastIV if start is poison. (PR #135666)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: Florian Hahn (fhahn) Changes Back-porting properly freezing of the start value during epilogue vectorization (https://github.com/llvm/llvm-project/commit/2bdc1a1337692a5743658ba6b680e5d914e684a4) is non-trivial. For the 20.x release, just disable epilogue vectorization for FindLastIV reductions where the start value may be poison or undef. Fixes https://github.com/llvm/llvm-project/issues/126836. --- Full diff: https://github.com/llvm/llvm-project/pull/135666.diff 3 Files Affected: - (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+10) - (added) llvm/test/Transforms/LoopVectorize/AArch64/epilog-iv-select-cmp.ll (+166) - (modified) llvm/test/Transforms/LoopVectorize/epilog-iv-select-cmp.ll (+72-11) ``diff diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 7cd395255163a..1baec6d6ca37b 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -4626,6 +4626,16 @@ bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization( return false; } + // Don't vectorize the epilogue, if there are FindLastIV recurrences with a + // start value may be undef or poison. Such start values would need freezing. + if (any_of(Legal->getReductionVars(), [](const auto &P) { +return RecurrenceDescriptor::isFindLastIVRecurrenceKind( + P.second.getRecurrenceKind()) && + !isGuaranteedNotToBeUndefOrPoison( + P.second.getRecurrenceStartValue()); + })) +return false; + // Epilogue vectorization code has not been auditted to ensure it handles // non-latch exits properly. It may be fine, but it needs auditted and // tested. diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/epilog-iv-select-cmp.ll b/llvm/test/Transforms/LoopVectorize/AArch64/epilog-iv-select-cmp.ll new file mode 100644 index 0..7355aed6ae65f --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/AArch64/epilog-iv-select-cmp.ll @@ -0,0 +1,166 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5 +; RUN: opt -passes=loop-vectorize -mtriple=arm64-apple-macosx -S %s | FileCheck %s + +define i8 @select_icmp_var_start(ptr %a, i8 %n, i8 %start) { +; CHECK-LABEL: define i8 @select_icmp_var_start( +; CHECK-SAME: ptr [[A:%.*]], i8 [[N:%.*]], i8 [[START:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT:[[TMP0:%.*]] = add i8 [[N]], -1 +; CHECK-NEXT:[[TMP1:%.*]] = zext i8 [[TMP0]] to i32 +; CHECK-NEXT:[[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1 +; CHECK-NEXT:[[MIN_ITERS_CHECK1:%.*]] = icmp ult i32 [[TMP2]], 32 +; CHECK-NEXT:br i1 [[MIN_ITERS_CHECK1]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] +; CHECK: [[VECTOR_PH]]: +; CHECK-NEXT:[[N_MOD_VF:%.*]] = urem i32 [[TMP2]], 32 +; CHECK-NEXT:[[N_VEC:%.*]] = sub i32 [[TMP2]], [[N_MOD_VF]] +; CHECK-NEXT:[[TMP3:%.*]] = trunc i32 [[N_VEC]] to i8 +; CHECK-NEXT:br label %[[VECTOR_BODY:.*]] +; CHECK: [[VECTOR_BODY]]: +; CHECK-NEXT:[[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT:[[VEC_IND:%.*]] = phi <16 x i8> [ , %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT:[[VEC_PHI:%.*]] = phi <16 x i8> [ splat (i8 -128), %[[VECTOR_PH]] ], [ [[TMP10:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT:[[VEC_PHI2:%.*]] = phi <16 x i8> [ splat (i8 -128), %[[VECTOR_PH]] ], [ [[TMP11:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT:[[STEP_ADD:%.*]] = add <16 x i8> [[VEC_IND]], splat (i8 16) +; CHECK-NEXT:[[INDEX4:%.*]] = trunc i32 [[INDEX]] to i8 +; CHECK-NEXT:[[TMP5:%.*]] = add i8 [[INDEX4]], 0 +; CHECK-NEXT:[[TMP8:%.*]] = getelementptr inbounds i8, ptr [[A]], i8 [[TMP5]] +; CHECK-NEXT:[[TMP9:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 0 +; CHECK-NEXT:[[TMP7:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 16 +; CHECK-NEXT:[[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[TMP9]], align 8 +; CHECK-NEXT:[[WIDE_LOAD3:%.*]] = load <16 x i8>, ptr [[TMP7]], align 8 +; CHECK-NEXT:[[TMP17:%.*]] = icmp eq <16 x i8> [[WIDE_LOAD]], splat (i8 3) +; CHECK-NEXT:[[TMP23:%.*]] = icmp eq <16 x i8> [[WIDE_LOAD3]], splat (i8 3) +; CHECK-NEXT:[[TMP10]] = select <16 x i1> [[TMP17]], <16 x i8> [[VEC_IND]], <16 x i8> [[VEC_PHI]] +; CHECK-NEXT:[[TMP11]] = select <16 x i1> [[TMP23]], <16 x i8> [[STEP_ADD]], <16 x i8> [[VEC_PHI2]] +; CHECK-NEXT:[[INDEX_NEXT]] = add nuw i32 [[INDEX]], 32 +; CHECK-NEXT:[[VEC_IND_NEXT]] = add <16 x i8> [[STEP_ADD]], splat (i8 16) +; CHECK-NEXT:[[TMP12:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] +; CHECK-NEXT:br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: [[MIDDLE_BLOCK]]: +;
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,113 @@ +//===- MCGOFFAttributes.h - Attributes of GOFF symbols ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Defines the various attribute collections defining GOFF symbols. +// +//===--===// + +#ifndef LLVM_MC_MCGOFFATTRIBUTES_H +#define LLVM_MC_MCGOFFATTRIBUTES_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/GOFF.h" + +namespace llvm { +namespace GOFF { +// An "External Symbol Definition" in the GOFF file has a type, and depending on +// the type a different subset of the fields is used. +// +// Unlike other formats, a 2 dimensional structure is used to define the +// location of data. For example, the equivalent of the ELF .text section is +// made up of a Section Definition (SD) and a class (Element Definition; ED). +// The name of the SD symbol depends on the application, while the class has the +// predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively. +// +// Data can be placed into this structure in 2 ways. First, the data (in a text +// record) can be associated with an ED symbol. To refer to data, a Label +// Definition (LD) is used to give an offset into the data a name. When binding, +// the whole data is pulled into the resulting executable, and the addresses +// given by the LD symbols are resolved. +// +// The alternative is to use a Part Definition (PR). In this case, the data (in +// a text record) is associated with the part. When binding, only the data of +// referenced PRs is pulled into the resulting binary. +// +// Both approaches are used, which means that the equivalent of a section in ELF +// results in 3 GOFF symbols, either SD/ED/LD or SD/ED/PR. Moreover, certain +// sections are fine with just defining SD/ED symbols. The SymbolMapper takes +// care of all those details. + +// Attributes for SD symbols. +struct SDAttr { + GOFF::ESDTaskingBehavior TaskingBehavior = GOFF::ESD_TA_Unspecified; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for ED symbols. +struct EDAttr { + bool IsReadOnly = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDAmode Amode; + GOFF::ESDRmode Rmode; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented; + GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; + GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; + GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; + GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; +}; + +// Attributes for LD symbols. +struct LDAttr { + bool IsRenamable = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for PR symbols. +struct PRAttr { + bool IsRenamable = false; + bool IsReadOnly = false; // Not documented. + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; + GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity = + GOFF::ESD_DSS_NoWarning; redstar wrote: On the other hand, this is the default value and we do not set it to a different value, thus we do not need to specify it. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [GlobalMerge][PPC] Don't merge globals in llvm.metadata section (#131801) (PR #134052)
https://github.com/amy-kwan approved this pull request. LGTM. https://github.com/llvm/llvm-project/pull/134052 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][CFI] Add test to check for '-flto' and '-fvisibility=' flags (PR #135892)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135892 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][CFI] Don't mix CFI and non-CFI flags on the same line (PR #135890)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135890 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][CFI] Don't mix CFI and non-CFI flags on the same line (PR #135890)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135890 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][CFI] Add test to check for '-flto' and '-fvisibility=' flags (PR #135892)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135892 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][Driver][CFI] Rename to clarify purpose of CFI runtime (PR #135885)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135885 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [NFC][Driver][CFI] Rename to clarify purpose of CFI runtime (PR #135885)
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/135885 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839) (PR #134014)
https://github.com/tstellar closed https://github.com/llvm/llvm-project/pull/134014 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 9c7d728 - [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839)
Author: ZhaoQi Date: 2025-04-15T13:10:22-07:00 New Revision: 9c7d72869876f3d816bafab24c9e50c4b58ef0f4 URL: https://github.com/llvm/llvm-project/commit/9c7d72869876f3d816bafab24c9e50c4b58ef0f4 DIFF: https://github.com/llvm/llvm-project/commit/9c7d72869876f3d816bafab24c9e50c4b58ef0f4.diff LOG: [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839) (cherry picked from commit 46968310cb837e4b32859edef2107080b828b117) Added: llvm/test/MC/LoongArch/Relocations/relocation-specifier.s Modified: Removed: llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll diff --git a/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll b/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll deleted file mode 100644 index d39454a51a445..0 --- a/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: llc --mtriple=loongarch32 --filetype=obj %s -o %t-la32 -; RUN: llvm-readelf -s %t-la32 | FileCheck %s --check-prefix=LA32 - -; RUN: llc --mtriple=loongarch64 --filetype=obj %s -o %t-la64 -; RUN: llvm-readelf -s %t-la64 | FileCheck %s --check-prefix=LA64 - -; LA32: Symbol table '.symtab' contains [[#]] entries: -; LA32-NEXT:Num:Value Size Type Bind Vis Ndx Name -; LA32: 0 TLS GLOBAL DEFAULT UND tls_sym - -; LA64: Symbol table '.symtab' contains [[#]] entries: -; LA64-NEXT:Num:Value Size Type Bind Vis Ndx Name -; LA64: 0 TLS GLOBAL DEFAULT UND tls_sym - -@tls_sym = external thread_local(localexec) global i32 - -define dso_local signext i32 @test_tlsle() nounwind { -entry: - %0 = call ptr @llvm.threadlocal.address.p0(ptr @tls_sym) - %1 = load i32, ptr %0 - ret i32 %1 -} - -declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) diff --git a/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s b/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s new file mode 100644 index 0..d0898aaab92fe --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc --filetype=obj --triple=loongarch32 %s -o %t-la32 +# RUN: llvm-readelf -rs %t-la32 | FileCheck %s --check-prefixes=CHECK,RELOC32 +# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t-la64 +# RUN: llvm-readelf -rs %t-la64 | FileCheck %s --check-prefixes=CHECK,RELOC64 + +## This test is similar to test/MC/CSKY/relocation-specifier.s. + +# RELOC32: '.rela.data' +# RELOC32: R_LARCH_32 .data + 0 + +# RELOC64: '.rela.data' +# RELOC64: R_LARCH_32 .data + 0 + +# CHECK: TLS GLOBAL DEFAULT UND gd +# CHECK: TLS GLOBAL DEFAULT UND ld +# CHECK: TLS GLOBAL DEFAULT UND ie +# CHECK: TLS GLOBAL DEFAULT UND le + +pcalau12i $t1, %gd_pc_hi20(gd) +pcalau12i $t1, %ld_pc_hi20(ld) +pcalau12i $t1, %ie_pc_hi20(ie) +lu12i.w $t1, %le_hi20_r(le) + +.data +local: +.long local ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839) (PR #134014)
https://github.com/llvmbot updated https://github.com/llvm/llvm-project/pull/134014 >From 9c7d72869876f3d816bafab24c9e50c4b58ef0f4 Mon Sep 17 00:00:00 2001 From: ZhaoQi Date: Wed, 2 Apr 2025 09:11:20 +0800 Subject: [PATCH] [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839) (cherry picked from commit 46968310cb837e4b32859edef2107080b828b117) --- .../CodeGen/LoongArch/fix-tle-le-sym-type.ll | 24 - .../Relocations/relocation-specifier.s| 26 +++ 2 files changed, 26 insertions(+), 24 deletions(-) delete mode 100644 llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll create mode 100644 llvm/test/MC/LoongArch/Relocations/relocation-specifier.s diff --git a/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll b/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll deleted file mode 100644 index d39454a51a445..0 --- a/llvm/test/CodeGen/LoongArch/fix-tle-le-sym-type.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: llc --mtriple=loongarch32 --filetype=obj %s -o %t-la32 -; RUN: llvm-readelf -s %t-la32 | FileCheck %s --check-prefix=LA32 - -; RUN: llc --mtriple=loongarch64 --filetype=obj %s -o %t-la64 -; RUN: llvm-readelf -s %t-la64 | FileCheck %s --check-prefix=LA64 - -; LA32: Symbol table '.symtab' contains [[#]] entries: -; LA32-NEXT:Num:Value Size Type Bind Vis Ndx Name -; LA32: 0 TLS GLOBAL DEFAULT UND tls_sym - -; LA64: Symbol table '.symtab' contains [[#]] entries: -; LA64-NEXT:Num:Value Size Type Bind Vis Ndx Name -; LA64: 0 TLS GLOBAL DEFAULT UND tls_sym - -@tls_sym = external thread_local(localexec) global i32 - -define dso_local signext i32 @test_tlsle() nounwind { -entry: - %0 = call ptr @llvm.threadlocal.address.p0(ptr @tls_sym) - %1 = load i32, ptr %0 - ret i32 %1 -} - -declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) diff --git a/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s b/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s new file mode 100644 index 0..d0898aaab92fe --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/relocation-specifier.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc --filetype=obj --triple=loongarch32 %s -o %t-la32 +# RUN: llvm-readelf -rs %t-la32 | FileCheck %s --check-prefixes=CHECK,RELOC32 +# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t-la64 +# RUN: llvm-readelf -rs %t-la64 | FileCheck %s --check-prefixes=CHECK,RELOC64 + +## This test is similar to test/MC/CSKY/relocation-specifier.s. + +# RELOC32: '.rela.data' +# RELOC32: R_LARCH_32 .data + 0 + +# RELOC64: '.rela.data' +# RELOC64: R_LARCH_32 .data + 0 + +# CHECK: TLS GLOBAL DEFAULT UND gd +# CHECK: TLS GLOBAL DEFAULT UND ld +# CHECK: TLS GLOBAL DEFAULT UND ie +# CHECK: TLS GLOBAL DEFAULT UND le + +pcalau12i $t1, %gd_pc_hi20(gd) +pcalau12i $t1, %ld_pc_hi20(ld) +pcalau12i $t1, %ie_pc_hi20(ie) +lu12i.w $t1, %le_hi20_r(le) + +.data +local: +.long local ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lldb] release/20.x: [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093) (PR #134079)
https://github.com/llvmbot updated https://github.com/llvm/llvm-project/pull/134079 >From dc9d4f9a700843e9a7456366aa7e4301089ae7b9 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 27 Mar 2025 12:44:56 +0100 Subject: [PATCH] [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093) Using argv[0] for this was incorrect. I'm ignoring LaunchInfo::SetArg0, as that's what darwin and windows launchers do (they use the first element of the args vector instead). I picked up the funny unit test re-exec method from the llvm unit tests. (cherry picked from commit 39e7efe1e4304544289d8d1b45f4d04d11b4a791) --- .../Host/posix/ProcessLauncherPosixFork.cpp | 8 +++- lldb/unittests/Host/HostTest.cpp | 43 ++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 7d856954684c4..903b18b10976c 100644 --- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -94,6 +94,7 @@ struct ForkLaunchInfo { bool debug; bool disable_aslr; std::string wd; + std::string executable; const char **argv; Environment::Envp envp; std::vector actions; @@ -194,7 +195,8 @@ struct ForkLaunchInfo { } // Execute. We should never return... - execve(info.argv[0], const_cast(info.argv), info.envp); + execve(info.executable.c_str(), const_cast(info.argv), + info.envp); #if defined(__linux__) if (errno == ETXTBSY) { @@ -207,7 +209,8 @@ struct ForkLaunchInfo { // Since this state should clear up quickly, wait a while and then give it // one more go. usleep(5); -execve(info.argv[0], const_cast(info.argv), info.envp); +execve(info.executable.c_str(), const_cast(info.argv), + info.envp); } #endif @@ -246,6 +249,7 @@ ForkLaunchInfo::ForkLaunchInfo(const ProcessLaunchInfo &info) debug(info.GetFlags().Test(eLaunchFlagDebug)), disable_aslr(info.GetFlags().Test(eLaunchFlagDisableASLR)), wd(info.GetWorkingDirectory().GetPath()), + executable(info.GetExecutableFile().GetPath()), argv(info.GetArguments().GetConstArgumentVector()), envp(FixupEnvironment(info.GetEnvironment())), actions(MakeForkActions(info)) {} diff --git a/lldb/unittests/Host/HostTest.cpp b/lldb/unittests/Host/HostTest.cpp index a1d8a3b7f485a..ed1df6de001ea 100644 --- a/lldb/unittests/Host/HostTest.cpp +++ b/lldb/unittests/Host/HostTest.cpp @@ -7,12 +7,24 @@ //===--===// #include "lldb/Host/Host.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Utility/ProcessInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" +#include using namespace lldb_private; using namespace llvm; +// From TestMain.cpp. +extern const char *TestMainArgv0; + +static cl::opt test_arg("test-arg"); + TEST(Host, WaitStatusFormat) { EXPECT_EQ("W01", formatv("{0:g}", WaitStatus{WaitStatus::Exit, 1}).str()); EXPECT_EQ("X02", formatv("{0:g}", WaitStatus{WaitStatus::Signal, 2}).str()); @@ -45,4 +57,33 @@ TEST(Host, ProcessInstanceInfoCumulativeSystemTimeIsValid) { EXPECT_TRUE(info.CumulativeSystemTimeIsValid()); info.SetCumulativeSystemTime(ProcessInstanceInfo::timespec{1, 0}); EXPECT_TRUE(info.CumulativeSystemTimeIsValid()); -} \ No newline at end of file +} + +TEST(Host, LaunchProcessSetsArgv0) { + SubsystemRAII subsystems; + + static constexpr StringLiteral TestArgv0 = "HelloArgv0"; + if (test_arg != 0) { +// In subprocess +if (TestMainArgv0 != TestArgv0) { + errs() << formatv("Got '{0}' for argv[0]\n", TestMainArgv0); + exit(1); +} +exit(0); + } + + ProcessLaunchInfo info; + info.SetExecutableFile( + FileSpec(llvm::sys::fs::getMainExecutable(TestMainArgv0, &test_arg)), + /*add_exe_file_as_first_arg=*/false); + info.GetArguments().AppendArgument("HelloArgv0"); + info.GetArguments().AppendArgument( + "--gtest_filter=Host.LaunchProcessSetsArgv0"); + info.GetArguments().AppendArgument("--test-arg=47"); + std::promise exit_status; + info.SetMonitorProcessCallback([&](lldb::pid_t pid, int signal, int status) { +exit_status.set_value(status); + }); + ASSERT_THAT_ERROR(Host::LaunchProcess(info).takeError(), Succeeded()); + ASSERT_THAT(exit_status.get_future().get(), 0); +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [LoongArch] Move fix-tle-le-sym-type test to test/MC. NFC (#133839) (PR #134014)
github-actions[bot] wrote: @zhaoqi5 (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/134014 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lldb] dc9d4f9 - [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093)
Author: Pavel Labath Date: 2025-04-15T13:11:58-07:00 New Revision: dc9d4f9a700843e9a7456366aa7e4301089ae7b9 URL: https://github.com/llvm/llvm-project/commit/dc9d4f9a700843e9a7456366aa7e4301089ae7b9 DIFF: https://github.com/llvm/llvm-project/commit/dc9d4f9a700843e9a7456366aa7e4301089ae7b9.diff LOG: [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093) Using argv[0] for this was incorrect. I'm ignoring LaunchInfo::SetArg0, as that's what darwin and windows launchers do (they use the first element of the args vector instead). I picked up the funny unit test re-exec method from the llvm unit tests. (cherry picked from commit 39e7efe1e4304544289d8d1b45f4d04d11b4a791) Added: Modified: lldb/source/Host/posix/ProcessLauncherPosixFork.cpp lldb/unittests/Host/HostTest.cpp Removed: diff --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 7d856954684c4..903b18b10976c 100644 --- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -94,6 +94,7 @@ struct ForkLaunchInfo { bool debug; bool disable_aslr; std::string wd; + std::string executable; const char **argv; Environment::Envp envp; std::vector actions; @@ -194,7 +195,8 @@ struct ForkLaunchInfo { } // Execute. We should never return... - execve(info.argv[0], const_cast(info.argv), info.envp); + execve(info.executable.c_str(), const_cast(info.argv), + info.envp); #if defined(__linux__) if (errno == ETXTBSY) { @@ -207,7 +209,8 @@ struct ForkLaunchInfo { // Since this state should clear up quickly, wait a while and then give it // one more go. usleep(5); -execve(info.argv[0], const_cast(info.argv), info.envp); +execve(info.executable.c_str(), const_cast(info.argv), + info.envp); } #endif @@ -246,6 +249,7 @@ ForkLaunchInfo::ForkLaunchInfo(const ProcessLaunchInfo &info) debug(info.GetFlags().Test(eLaunchFlagDebug)), disable_aslr(info.GetFlags().Test(eLaunchFlagDisableASLR)), wd(info.GetWorkingDirectory().GetPath()), + executable(info.GetExecutableFile().GetPath()), argv(info.GetArguments().GetConstArgumentVector()), envp(FixupEnvironment(info.GetEnvironment())), actions(MakeForkActions(info)) {} diff --git a/lldb/unittests/Host/HostTest.cpp b/lldb/unittests/Host/HostTest.cpp index a1d8a3b7f485a..ed1df6de001ea 100644 --- a/lldb/unittests/Host/HostTest.cpp +++ b/lldb/unittests/Host/HostTest.cpp @@ -7,12 +7,24 @@ //===--===// #include "lldb/Host/Host.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Utility/ProcessInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" +#include using namespace lldb_private; using namespace llvm; +// From TestMain.cpp. +extern const char *TestMainArgv0; + +static cl::opt test_arg("test-arg"); + TEST(Host, WaitStatusFormat) { EXPECT_EQ("W01", formatv("{0:g}", WaitStatus{WaitStatus::Exit, 1}).str()); EXPECT_EQ("X02", formatv("{0:g}", WaitStatus{WaitStatus::Signal, 2}).str()); @@ -45,4 +57,33 @@ TEST(Host, ProcessInstanceInfoCumulativeSystemTimeIsValid) { EXPECT_TRUE(info.CumulativeSystemTimeIsValid()); info.SetCumulativeSystemTime(ProcessInstanceInfo::timespec{1, 0}); EXPECT_TRUE(info.CumulativeSystemTimeIsValid()); -} \ No newline at end of file +} + +TEST(Host, LaunchProcessSetsArgv0) { + SubsystemRAII subsystems; + + static constexpr StringLiteral TestArgv0 = "HelloArgv0"; + if (test_arg != 0) { +// In subprocess +if (TestMainArgv0 != TestArgv0) { + errs() << formatv("Got '{0}' for argv[0]\n", TestMainArgv0); + exit(1); +} +exit(0); + } + + ProcessLaunchInfo info; + info.SetExecutableFile( + FileSpec(llvm::sys::fs::getMainExecutable(TestMainArgv0, &test_arg)), + /*add_exe_file_as_first_arg=*/false); + info.GetArguments().AppendArgument("HelloArgv0"); + info.GetArguments().AppendArgument( + "--gtest_filter=Host.LaunchProcessSetsArgv0"); + info.GetArguments().AppendArgument("--test-arg=47"); + std::promise exit_status; + info.SetMonitorProcessCallback([&](lldb::pid_t pid, int signal, int status) { +exit_status.set_value(status); + }); + ASSERT_THAT_ERROR(Host::LaunchProcess(info).takeError(), Succeeded()); + ASSERT_THAT(exit_status.get_future().get(), 0); +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lldb] release/20.x: [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093) (PR #134079)
https://github.com/tstellar closed https://github.com/llvm/llvm-project/pull/134079 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lldb] release/20.x: [lldb] Respect LaunchInfo::SetExecutable in ProcessLauncherPosixFork (#133093) (PR #134079)
github-actions[bot] wrote: @DavidSpickett (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/134079 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] dfd6f12 - [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921)
Author: Louis Dionne Date: 2025-04-15T13:14:13-07:00 New Revision: dfd6f123362acc94eb99c4e0440fa166b40153e4 URL: https://github.com/llvm/llvm-project/commit/dfd6f123362acc94eb99c4e0440fa166b40153e4 DIFF: https://github.com/llvm/llvm-project/commit/dfd6f123362acc94eb99c4e0440fa166b40153e4.diff LOG: [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921) There were some remaining headers that were not guarded with _LIBCPP_HAS_LOCALIZATION, leading to errors when trying to use modules on platforms that don't support localization (since all the headers get pulled in when building the 'std' module). This patch brings these headers in line with what we do for every other header that depends on localization. This patch also requires including from <__configuration/platform.h> in order to define _NEWLIB_VERSION. In the long term, we should use a better approach for doing that, such as defining a macro in the __config_site header. (cherry picked from commit 4090910a695efcba4b484e9f8ad2b564e9a4e7ed) Added: Modified: libcxx/include/__configuration/platform.h libcxx/include/__locale libcxx/include/__locale_dir/locale_base_api.h libcxx/include/fstream libcxx/include/regex libcxx/include/strstream libcxx/test/configs/armv7m-picolibc-libc++.cfg.in libcxx/test/libcxx/system_reserved_names.gen.py Removed: diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h index 8d0f8f63f5213..f3c199dee172b 100644 --- a/libcxx/include/__configuration/platform.h +++ b/libcxx/include/__configuration/platform.h @@ -42,6 +42,13 @@ # endif #endif +// This is required in order for _NEWLIB_VERSION to be defined in places where we use it. +// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid +// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism. +#if __has_include() +# include +#endif + #ifndef __BYTE_ORDER__ # error \ "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform" diff --git a/libcxx/include/__locale b/libcxx/include/__locale index dfe79d5e506f1..93187dc1d0d9c 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -11,6 +11,9 @@ #define _LIBCPP___LOCALE #include <__config> + +#if _LIBCPP_HAS_LOCALIZATION + #include <__locale_dir/locale_base_api.h> #include <__memory/shared_count.h> #include <__mutex/once_flag.h> @@ -24,18 +27,18 @@ #include // Some platforms require more includes than others. Keep the includes on all plaforms for now. -#include -#include +# include +# include -#if _LIBCPP_HAS_WIDE_CHARACTERS -# include -#else -# include <__std_mbstate_t.h> -#endif +# if _LIBCPP_HAS_WIDE_CHARACTERS +#include +# else +#include <__std_mbstate_t.h> +# endif -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +# endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -85,9 +88,9 @@ public: // locale operations: string name() const; bool operator==(const locale&) const; -#if _LIBCPP_STD_VER <= 17 +# if _LIBCPP_STD_VER <= 17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); } -#endif +# endif template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const; @@ -237,9 +240,9 @@ long collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) cons } extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate; -#if _LIBCPP_HAS_WIDE_CHARACTERS +# if _LIBCPP_HAS_WIDE_CHARACTERS extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate; -#endif +# endif // template class collate_byname; @@ -264,7 +267,7 @@ protected: string_type do_transform(const char_type* __lo, const char_type* __hi) const override; }; -#if _LIBCPP_HAS_WIDE_CHARACTERS +# if _LIBCPP_HAS_WIDE_CHARACTERS template <> class _LIBCPP_EXPORTED_FROM_ABI collate_byname : public collate { __locale::__locale_t __l_; @@ -283,7 +286,7 @@ protected: const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override; string_type do_transform(const char_type* __lo, const char_type* __hi) const override; }; -#endif +# endif template bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, @@ -296,7 +299,7 @@ bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, class _LIBCPP_EXPORTED_FROM_ABI ctype_base { publ
[llvm-branch-commits] [libcxx] [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921) (PR #134406)
https://github.com/tstellar updated https://github.com/llvm/llvm-project/pull/134406 >From dfd6f123362acc94eb99c4e0440fa166b40153e4 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 4 Apr 2025 11:48:46 -0400 Subject: [PATCH] [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921) There were some remaining headers that were not guarded with _LIBCPP_HAS_LOCALIZATION, leading to errors when trying to use modules on platforms that don't support localization (since all the headers get pulled in when building the 'std' module). This patch brings these headers in line with what we do for every other header that depends on localization. This patch also requires including from <__configuration/platform.h> in order to define _NEWLIB_VERSION. In the long term, we should use a better approach for doing that, such as defining a macro in the __config_site header. (cherry picked from commit 4090910a695efcba4b484e9f8ad2b564e9a4e7ed) --- libcxx/include/__configuration/platform.h | 7 + libcxx/include/__locale | 153 - libcxx/include/__locale_dir/locale_base_api.h | 112 +++ libcxx/include/fstream| 55 ++-- libcxx/include/regex | 290 +- libcxx/include/strstream | 55 ++-- .../configs/armv7m-picolibc-libc++.cfg.in | 4 - .../test/libcxx/system_reserved_names.gen.py | 6 + 8 files changed, 356 insertions(+), 326 deletions(-) diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h index 8d0f8f63f5213..f3c199dee172b 100644 --- a/libcxx/include/__configuration/platform.h +++ b/libcxx/include/__configuration/platform.h @@ -42,6 +42,13 @@ # endif #endif +// This is required in order for _NEWLIB_VERSION to be defined in places where we use it. +// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid +// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism. +#if __has_include() +# include +#endif + #ifndef __BYTE_ORDER__ # error \ "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform" diff --git a/libcxx/include/__locale b/libcxx/include/__locale index dfe79d5e506f1..93187dc1d0d9c 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -11,6 +11,9 @@ #define _LIBCPP___LOCALE #include <__config> + +#if _LIBCPP_HAS_LOCALIZATION + #include <__locale_dir/locale_base_api.h> #include <__memory/shared_count.h> #include <__mutex/once_flag.h> @@ -24,18 +27,18 @@ #include // Some platforms require more includes than others. Keep the includes on all plaforms for now. -#include -#include +# include +# include -#if _LIBCPP_HAS_WIDE_CHARACTERS -# include -#else -# include <__std_mbstate_t.h> -#endif +# if _LIBCPP_HAS_WIDE_CHARACTERS +#include +# else +#include <__std_mbstate_t.h> +# endif -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +# endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -85,9 +88,9 @@ public: // locale operations: string name() const; bool operator==(const locale&) const; -#if _LIBCPP_STD_VER <= 17 +# if _LIBCPP_STD_VER <= 17 _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); } -#endif +# endif template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const; @@ -237,9 +240,9 @@ long collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) cons } extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate; -#if _LIBCPP_HAS_WIDE_CHARACTERS +# if _LIBCPP_HAS_WIDE_CHARACTERS extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate; -#endif +# endif // template class collate_byname; @@ -264,7 +267,7 @@ protected: string_type do_transform(const char_type* __lo, const char_type* __hi) const override; }; -#if _LIBCPP_HAS_WIDE_CHARACTERS +# if _LIBCPP_HAS_WIDE_CHARACTERS template <> class _LIBCPP_EXPORTED_FROM_ABI collate_byname : public collate { __locale::__locale_t __l_; @@ -283,7 +286,7 @@ protected: const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override; string_type do_transform(const char_type* __lo, const char_type* __hi) const override; }; -#endif +# endif template bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, @@ -296,7 +299,7 @@ bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, class _LIBCPP_EXPORTED
[llvm-branch-commits] [libcxx] [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921) (PR #134406)
https://github.com/tstellar closed https://github.com/llvm/llvm-project/pull/134406 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] 86c9853 - [libc++] Fix deployment targets that were incorrectly bumped (#134278)
Author: Louis Dionne Date: 2025-04-15T13:15:42-07:00 New Revision: 86c98536380ba34969a8e24f793bc425af28c05e URL: https://github.com/llvm/llvm-project/commit/86c98536380ba34969a8e24f793bc425af28c05e DIFF: https://github.com/llvm/llvm-project/commit/86c98536380ba34969a8e24f793bc425af28c05e.diff LOG: [libc++] Fix deployment targets that were incorrectly bumped (#134278) When I introduced the various `_LIBCPP_INTRODUCED_IN_LLVM_XY_ATTRIBUTE` macros in 182f5e9b2f03, I tried to correlate them to the right OS versions, but it seems that I made a few mistakes. This wasn't caught in the CI because we don't test back-deployment that far. rdar://148405946 (cherry picked from commit a97f73405f8e074263a0ed2dd2b8c87c014f46d9) Added: Modified: libcxx/include/__configuration/availability.h Removed: diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h index 261cf9c1ae9d8..f9e52a690c05c 100644 --- a/libcxx/include/__configuration/availability.h +++ b/libcxx/include/__configuration/availability.h @@ -163,10 +163,10 @@ __attribute__((availability(driverkit, strict, introduced = 23.0))) // LLVM 15 -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130400) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160500) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160500) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90500) ||\ +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300) ||\ (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 70500) || \ (defined(__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__ < 220400) #define _LIBCPP_INTRODUCED_IN_LLVM_15 0 @@ -174,10 +174,10 @@ #define _LIBCPP_INTRODUCED_IN_LLVM_15 1 # endif # define _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE \ -__attribute__((availability(macos, strict, introduced = 13.4))) \ -__attribute__((availability(ios, strict, introduced = 16.5))) \ -__attribute__((availability(tvos, strict, introduced = 16.5))) \ -__attribute__((availability(watchos, strict, introduced = 9.5))) \ +__attribute__((availability(macos, strict, introduced = 13.3))) \ +__attribute__((availability(ios, strict, introduced = 16.3))) \ +__attribute__((availability(tvos, strict, introduced = 16.3))) \ +__attribute__((availability(watchos, strict, introduced = 9.3))) \ __attribute__((availability(bridgeos, strict, introduced = 7.5))) \ __attribute__((availability(driverkit, strict, introduced = 22.4))) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] release/20.x: [libc++] Fix deployment targets that were incorrectly bumped (#134278) (PR #134435)
https://github.com/llvmbot updated https://github.com/llvm/llvm-project/pull/134435 >From 86c98536380ba34969a8e24f793bc425af28c05e Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 4 Apr 2025 14:56:26 -0400 Subject: [PATCH] [libc++] Fix deployment targets that were incorrectly bumped (#134278) When I introduced the various `_LIBCPP_INTRODUCED_IN_LLVM_XY_ATTRIBUTE` macros in 182f5e9b2f03, I tried to correlate them to the right OS versions, but it seems that I made a few mistakes. This wasn't caught in the CI because we don't test back-deployment that far. rdar://148405946 (cherry picked from commit a97f73405f8e074263a0ed2dd2b8c87c014f46d9) --- libcxx/include/__configuration/availability.h | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libcxx/include/__configuration/availability.h b/libcxx/include/__configuration/availability.h index 261cf9c1ae9d8..f9e52a690c05c 100644 --- a/libcxx/include/__configuration/availability.h +++ b/libcxx/include/__configuration/availability.h @@ -163,10 +163,10 @@ __attribute__((availability(driverkit, strict, introduced = 23.0))) // LLVM 15 -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130400) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160500) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160500) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90500) ||\ +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300) ||\ (defined(__ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_BRIDGE_OS_VERSION_MIN_REQUIRED__ < 70500) || \ (defined(__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__ < 220400) #define _LIBCPP_INTRODUCED_IN_LLVM_15 0 @@ -174,10 +174,10 @@ #define _LIBCPP_INTRODUCED_IN_LLVM_15 1 # endif # define _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE \ -__attribute__((availability(macos, strict, introduced = 13.4))) \ -__attribute__((availability(ios, strict, introduced = 16.5))) \ -__attribute__((availability(tvos, strict, introduced = 16.5))) \ -__attribute__((availability(watchos, strict, introduced = 9.5))) \ +__attribute__((availability(macos, strict, introduced = 13.3))) \ +__attribute__((availability(ios, strict, introduced = 16.3))) \ +__attribute__((availability(tvos, strict, introduced = 16.3))) \ +__attribute__((availability(watchos, strict, introduced = 9.3))) \ __attribute__((availability(bridgeos, strict, introduced = 7.5))) \ __attribute__((availability(driverkit, strict, introduced = 22.4))) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] [libc++] Guard additional headers with _LIBCPP_HAS_LOCALIZATION (#131921) (PR #134406)
github-actions[bot] wrote: @ldionne (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/134406 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] release/20.x: [libc++] Fix deployment targets that were incorrectly bumped (#134278) (PR #134435)
github-actions[bot] wrote: @ldionne (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. https://github.com/llvm/llvm-project/pull/134435 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [libcxx] release/20.x: [libc++] Fix deployment targets that were incorrectly bumped (#134278) (PR #134435)
https://github.com/tstellar closed https://github.com/llvm/llvm-project/pull/134435 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [LLVM][MemCpyOpt] Unify alias tags if we optimize allocas (#129537) (PR #135615)
https://github.com/tstellar closed https://github.com/llvm/llvm-project/pull/135615 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20.x: [LLVM][MemCpyOpt] Unify alias tags if we optimize allocas (#129537) (PR #135615)
tstellar wrote: Merged: 2131242240f71926e45e58ad6ec66aced4756e48 https://github.com/llvm/llvm-project/pull/135615 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 2131242 - [LLVM][MemCpyOpt] Unify alias tags if we optimize allocas (#129537)
Author: Dominik Adamski Date: 2025-04-15T13:17:35-07:00 New Revision: 2131242240f71926e45e58ad6ec66aced4756e48 URL: https://github.com/llvm/llvm-project/commit/2131242240f71926e45e58ad6ec66aced4756e48 DIFF: https://github.com/llvm/llvm-project/commit/2131242240f71926e45e58ad6ec66aced4756e48.diff LOG: [LLVM][MemCpyOpt] Unify alias tags if we optimize allocas (#129537) Optimization of alloca instructions may lead to invalid alias tags. Incorrect alias tags can result in incorrect optimization outcomes for Fortran source code compiled by Flang with flags: `-O3 -mmlir -local-alloc-tbaa -flto`. This commit removes alias tags when memcpy optimization replaces two arrays with one array, thus ensuring correct compilation of Fortran source code using flags: `-O3 -mmlir -local-alloc-tbaa -flto`. This commit is also a proposal to fix the reported issue: https://github.com/llvm/llvm-project/issues/133984 - Co-authored-by: Shilei Tian (cherry picked from commit 716b02d8c575afde7af1af13df145019659abca2) Added: llvm/test/Transforms/MemCpyOpt/memcpy-tbaa.ll Modified: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp llvm/test/Transforms/MemCpyOpt/stack-move.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 971d6012f6129..9202c341da92e 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1518,7 +1518,7 @@ bool MemCpyOptPass::performStackMoveOptzn(Instruction *Load, Instruction *Store, // to remove them. SmallVector LifetimeMarkers; - SmallSet NoAliasInstrs; + SmallSet AAMetadataInstrs; bool SrcNotDom = false; // Recursively track the user and check whether modified alias exist. @@ -1573,8 +1573,8 @@ bool MemCpyOptPass::performStackMoveOptzn(Instruction *Load, Instruction *Store, continue; } } - if (UI->hasMetadata(LLVMContext::MD_noalias)) -NoAliasInstrs.insert(UI); + AAMetadataInstrs.insert(UI); + if (!ModRefCallback(UI)) return false; } @@ -1679,11 +1679,16 @@ bool MemCpyOptPass::performStackMoveOptzn(Instruction *Load, Instruction *Store, } // As this transformation can cause memory accesses that didn't previously - // alias to begin to alias one another, we remove !noalias metadata from any - // uses of either alloca. This is conservative, but more precision doesn't - // seem worthwhile right now. - for (Instruction *I : NoAliasInstrs) + // alias to begin to alias one another, we remove !alias.scope, !noalias, + // !tbaa and !tbaa_struct metadata from any uses of either alloca. + // This is conservative, but more precision doesn't seem worthwhile + // right now. + for (Instruction *I : AAMetadataInstrs) { +I->setMetadata(LLVMContext::MD_alias_scope, nullptr); I->setMetadata(LLVMContext::MD_noalias, nullptr); +I->setMetadata(LLVMContext::MD_tbaa, nullptr); +I->setMetadata(LLVMContext::MD_tbaa_struct, nullptr); + } LLVM_DEBUG(dbgs() << "Stack Move: Performed staack-move optimization\n"); NumStackMove++; diff --git a/llvm/test/Transforms/MemCpyOpt/memcpy-tbaa.ll b/llvm/test/Transforms/MemCpyOpt/memcpy-tbaa.ll new file mode 100644 index 0..6e446e5ff267c --- /dev/null +++ b/llvm/test/Transforms/MemCpyOpt/memcpy-tbaa.ll @@ -0,0 +1,77 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=memcpyopt,dse -S -verify-memoryssa | FileCheck %s + +define void @test() local_unnamed_addr { +; CHECK-LABEL: define void @test() local_unnamed_addr { +; CHECK-NEXT:[[TEST_ARRAY_B:%.*]] = alloca [31 x float], align 4 +; CHECK-NEXT:[[TMP1:%.*]] = getelementptr float, ptr [[TEST_ARRAY_B]], i64 1 +; CHECK-NEXT:store float 0x3E6AA5188000, ptr [[TMP1]], align 4 +; CHECK-NEXT:[[TMP2:%.*]] = getelementptr float, ptr [[TEST_ARRAY_B]], i64 1 +; CHECK-NEXT:[[TMP3:%.*]] = load float, ptr [[TMP2]], align 4 +; CHECK-NEXT:ret void +; + %test_array_a = alloca [31 x float], align 4 + %test_array_b = alloca [31 x float], align 4 + %1 = getelementptr float, ptr %test_array_b, i64 1 + store float 0x3E6AA5188000, ptr %1, align 4, !tbaa !4 + call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(124) %test_array_a, ptr noundef nonnull align 4 dereferenceable(124) %test_array_b, i64 124, i1 false) + %2 = getelementptr float, ptr %test_array_a, i64 1 + %3 = load float, ptr %2, align 4, !tbaa !7 + ret void +} + +%struct.Outer = type { float, double, %struct.Inner } +%struct.Inner = type { i32, float } + +; Function Attrs: nounwind uwtable +define dso_local float @f() { +; CHECK-LABEL: define dso_local float @f() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT:[[TEST1:%.*]] = alloca [[STRUCT_
[llvm-branch-commits] [llvm] [llvm][IR] Treat memcmp and bcmp as libcalls (PR #135706)
ilovepi wrote: > I'm surprised these missing libcalls have been missing for so long without > getting fixed I think few people are doing LTO w/ things that provide bcmp/memcmp, like libc. Typically ,what I see is that even when they're statically linked, like for embeded code, they're not built w/ LTO, so its just a normal library, and not participating in LTO. https://github.com/llvm/llvm-project/pull/135706 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
@@ -294,4 +294,13 @@ def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; // VIS3 instruction patterns. let Predicates = [HasVIS3] in { def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 ยง7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), +(ANDrr (SRAXri $rhs, 63), $lhs)))>; s-barannikov wrote: Thanks for trying. It probably needs more work at SparcTargetLowering for the expansion to be optimal. Can you add a TODO near the pattern that reads something like "Consider moving this expansion to DAG legalization phase"? (For the record: I don't really understand the expansion and assume it is taken from a proved source, like Sparc architecture manual.) https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
https://github.com/s-barannikov approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
https://github.com/s-barannikov edited https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)
https://github.com/s-barannikov edited https://github.com/llvm/llvm-project/pull/135715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)
https://github.com/s-barannikov edited https://github.com/llvm/llvm-project/pull/135715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use native bitcast instructions when we have VIS3 (PR #135716)
https://github.com/s-barannikov approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/135716 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,113 @@ +//===- MCGOFFAttributes.h - Attributes of GOFF symbols ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Defines the various attribute collections defining GOFF symbols. +// +//===--===// + +#ifndef LLVM_MC_MCGOFFATTRIBUTES_H +#define LLVM_MC_MCGOFFATTRIBUTES_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/GOFF.h" + +namespace llvm { +namespace GOFF { +// An "External Symbol Definition" in the GOFF file has a type, and depending on +// the type a different subset of the fields is used. +// +// Unlike other formats, a 2 dimensional structure is used to define the +// location of data. For example, the equivalent of the ELF .text section is +// made up of a Section Definition (SD) and a class (Element Definition; ED). +// The name of the SD symbol depends on the application, while the class has the +// predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively. +// +// Data can be placed into this structure in 2 ways. First, the data (in a text +// record) can be associated with an ED symbol. To refer to data, a Label +// Definition (LD) is used to give an offset into the data a name. When binding, +// the whole data is pulled into the resulting executable, and the addresses +// given by the LD symbols are resolved. +// +// The alternative is to use a Part Definition (PR). In this case, the data (in +// a text record) is associated with the part. When binding, only the data of +// referenced PRs is pulled into the resulting binary. +// +// Both approaches are used, which means that the equivalent of a section in ELF +// results in 3 GOFF symbols, either SD/ED/LD or SD/ED/PR. Moreover, certain +// sections are fine with just defining SD/ED symbols. The SymbolMapper takes +// care of all those details. + +// Attributes for SD symbols. +struct SDAttr { + GOFF::ESDTaskingBehavior TaskingBehavior = GOFF::ESD_TA_Unspecified; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for ED symbols. +struct EDAttr { + bool IsReadOnly = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDAmode Amode; + GOFF::ESDRmode Rmode; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented; + GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; + GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; + GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; + GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; +}; + +// Attributes for LD symbols. +struct LDAttr { + bool IsRenamable = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong; redstar wrote: This is actually needed for C++ inline functions etc. which can end up in several object files. Also for weak definitions, e.g.: ``` // a.c #include __attribute__((weak)) void fun() { printf("Weak fun\n"); } void feature() { fun(); } ``` and ``` #include extern void feature(); void fun() { printf("Other fun\n"); } int main(int argc, char *argv[]) { feature(); return 0; } ``` (example taken from a blog by @MaskRay) Another case were the documentation needs an update. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] Store GUIDs in metadata (PR #133682)
https://github.com/orodley updated https://github.com/llvm/llvm-project/pull/133682 >From 9d34fae78840876402a1b049d345b73285ffe4e5 Mon Sep 17 00:00:00 2001 From: Owen Rodley Date: Mon, 31 Mar 2025 16:16:35 +1100 Subject: [PATCH] Store GUIDs in metadata This takes the existing AssignGUID pass from CtxProfAnalysis, and runs it by default, at the appropriate stages of the LTO pipeline. It also changes GlobalValue::getGUID() to retrieve the GUID from the metadata instead of computing it. We don't yet have the supporting downstream changes to make a dedicated GUID table in bitcode, nor do we use the metadata as part of ThinLTO -- it retains its existing mechanisms of recomputing GUIDs from separately saved data. That will be changed later. --- llvm/include/llvm/Analysis/CtxProfAnalysis.h | 38 - llvm/include/llvm/IR/FixedMetadataKinds.def | 1 + llvm/include/llvm/IR/GlobalValue.h| 6 +-- .../llvm/Transforms/Utils/AssignGUID.h| 34 +++ llvm/lib/Analysis/CtxProfAnalysis.cpp | 42 ++- llvm/lib/IR/Globals.cpp | 34 +++ llvm/lib/Passes/PassBuilder.cpp | 1 + llvm/lib/Passes/PassBuilderPipelines.cpp | 9 +++- .../Instrumentation/PGOCtxProfFlattening.cpp | 2 +- .../Instrumentation/PGOCtxProfLowering.cpp| 3 +- llvm/lib/Transforms/Utils/AssignGUID.cpp | 34 +++ llvm/lib/Transforms/Utils/CMakeLists.txt | 1 + .../Transforms/Utils/CallPromotionUtils.cpp | 5 +-- llvm/lib/Transforms/Utils/InlineFunction.cpp | 4 +- 14 files changed, 131 insertions(+), 83 deletions(-) create mode 100644 llvm/include/llvm/Transforms/Utils/AssignGUID.h create mode 100644 llvm/lib/Transforms/Utils/AssignGUID.cpp diff --git a/llvm/include/llvm/Analysis/CtxProfAnalysis.h b/llvm/include/llvm/Analysis/CtxProfAnalysis.h index 6f1c3696ca78c..2ca21fc154f9a 100644 --- a/llvm/include/llvm/Analysis/CtxProfAnalysis.h +++ b/llvm/include/llvm/Analysis/CtxProfAnalysis.h @@ -46,9 +46,6 @@ class PGOContextualProfile { // we'll need when we maintain the profiles during IPO transformations. std::map FuncInfo; - /// Get the GUID of this Function if it's defined in this module. - GlobalValue::GUID getDefinedFunctionGUID(const Function &F) const; - // This is meant to be constructed from CtxProfAnalysis, which will also set // its state piecemeal. PGOContextualProfile() = default; @@ -67,9 +64,9 @@ class PGOContextualProfile { bool isInSpecializedModule() const; - bool isFunctionKnown(const Function &F) const { -return getDefinedFunctionGUID(F) != 0; - } + bool isInSpecializedModule() const; + + bool isFunctionKnown(const Function &F) const { return F.getGUID() != 0; } StringRef getFunctionName(GlobalValue::GUID GUID) const { auto It = FuncInfo.find(GUID); @@ -80,22 +77,22 @@ class PGOContextualProfile { uint32_t getNumCounters(const Function &F) const { assert(isFunctionKnown(F)); -return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex; +return FuncInfo.find(F.getGUID())->second.NextCounterIndex; } uint32_t getNumCallsites(const Function &F) const { assert(isFunctionKnown(F)); -return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex; +return FuncInfo.find(F.getGUID())->second.NextCallsiteIndex; } uint32_t allocateNextCounterIndex(const Function &F) { assert(isFunctionKnown(F)); -return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex++; +return FuncInfo.find(F.getGUID())->second.NextCounterIndex++; } uint32_t allocateNextCallsiteIndex(const Function &F) { assert(isFunctionKnown(F)); -return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex++; +return FuncInfo.find(F.getGUID())->second.NextCallsiteIndex++; } using ConstVisitor = function_ref; @@ -157,26 +154,5 @@ class CtxProfAnalysisPrinterPass const PrintMode Mode; }; -/// Assign a GUID to functions as metadata. GUID calculation takes linkage into -/// account, which may change especially through and after thinlto. By -/// pre-computing and assigning as metadata, this mechanism is resilient to such -/// changes (as well as name changes e.g. suffix ".llvm." additions). - -// FIXME(mtrofin): we can generalize this mechanism to calculate a GUID early in -// the pass pipeline, associate it with any Global Value, and then use it for -// PGO and ThinLTO. -// At that point, this should be moved elsewhere. -class AssignGUIDPass : public PassInfoMixin { -public: - explicit AssignGUIDPass() = default; - - /// Assign a GUID *if* one is not already assign, as a function metadata named - /// `GUIDMetadataName`. - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); - static const char *GUIDMetadataName; - // This should become GlobalValue::getGUID - static uint64_t getGUID(const Function &F); -}; - } // namespace llvm #en
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,145 @@ +//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/MC/MCSectionGOFF.h" +#include "llvm/BinaryFormat/GOFF.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) { + if (Rmode != GOFF::ESD_RMODE_None) { +OS << "RMODE" << (UseParenthesis ? '(' : ' '); +switch (Rmode) { +case GOFF::ESD_RMODE_24: + OS << "24"; + break; +case GOFF::ESD_RMODE_31: + OS << "31"; + break; +case GOFF::ESD_RMODE_64: + OS << "64"; + break; +case GOFF::ESD_RMODE_None: + break; +} +if (UseParenthesis) + OS << ')'; + } +} + +void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName, + bool EmitAmodeAndRmode, GOFF::ESDAmode Amode, + GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment, + GOFF::ESDLoadingBehavior LoadBehavior, + GOFF::ESDExecutable Executable, bool IsReadOnly, + StringRef PartName) { + if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) { +OS << ParentName << " AMODE "; +switch (Amode) { +case GOFF::ESD_AMODE_24: + OS << "24"; + break; +case GOFF::ESD_AMODE_31: + OS << "31"; + break; +case GOFF::ESD_AMODE_ANY: + OS << "ANY"; + break; +case GOFF::ESD_AMODE_64: + OS << "64"; + break; +case GOFF::ESD_AMODE_MIN: + OS << "ANY64"; + break; +case GOFF::ESD_AMODE_None: + break; +} +OS << "\n"; + } + if (EmitAmodeAndRmode && Rmode != GOFF::ESD_RMODE_None) { +OS << ParentName << ' '; +emitRMode(OS, Rmode, /*UseParenthesis=*/false); +OS << "\n"; + } + OS << Name << " CATTR "; + OS << "ALIGN(" << static_cast(Alignment) << ")"; + switch (LoadBehavior) { + case GOFF::ESD_LB_Deferred: +OS << ",DEFLOAD"; +break; + case GOFF::ESD_LB_NoLoad: +OS << ",NOLOAD"; +break; + default: +break; + } + switch (Executable) { + case GOFF::ESD_EXE_CODE: +OS << ",EXECUTABLE"; +break; + case GOFF::ESD_EXE_DATA: +OS << ",NOTEXECUTABLE"; +break; + default: +break; + } + if (IsReadOnly) +OS << ",READONLY"; + if (Rmode != GOFF::ESD_RMODE_None) { +OS << ','; +emitRMode(OS, Rmode, /*UseParenthesis=*/true); + } + if (!PartName.empty()) +OS << ",PART(" << PartName << ")"; + OS << '\n'; +} +} // namespace + +void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, + raw_ostream &OS, + uint32_t Subsection) const { + switch (SymbolType) { + case GOFF::ESD_ST_SectionDefinition: { +OS << Name << " CSECT\n"; +Emitted = true; +break; + } + case GOFF::ESD_ST_ElementDefinition: { +bool ParentEmitted = getParent()->Emitted; +getParent()->printSwitchToSection(MAI, T, OS, Subsection); +if (!Emitted) { + emitCATTR(OS, Name, getParent()->getName(), !ParentEmitted, +EDAttributes.Amode, EDAttributes.Rmode, EDAttributes.Alignment, +EDAttributes.LoadBehavior, EDAttributes.Executable, +EDAttributes.IsReadOnly, StringRef()); + Emitted = true; +} else + OS << Name << " CATTR ,\n"; +break; + } + case GOFF::ESD_ST_PartReference: { +MCSectionGOFF *ED = getParent(); +bool SDEmitted = ED->getParent()->Emitted; +ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection); +if (!Emitted) { + emitCATTR(OS, ED->getName(), ED->getParent()->getName(), !SDEmitted, +PRAttributes.Amode, getParent()->EDAttributes.Rmode, +PRAttributes.Alignment, getParent()->EDAttributes.LoadBehavior, redstar wrote: The HLASM statement ``` C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a) ``` generates both the ED symbol `C_WSA64` and the PR symbol `a`. At the ED symbol, Rmode and LoadBehaviour are set. At the PR symbol, Amode (derived from RMode) and the LoadBehaviour are set. The latter looks like a HLASM bug. I am not aware of a way to defined the class (ED) and the part (PR) separately. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] llvm-reduce: Preserve uselistorder when writing thinlto bitcode (PR #133369)
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/133369 >From f056830c8eda3fab39cf73dad981b7b7091bdeb6 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 28 Mar 2025 10:46:08 +0700 Subject: [PATCH 1/2] llvm-reduce: Preserve uselistorder when writing thinlto bitcode Fixes #63621 --- .../thinlto-preserve-uselistorder.ll | 19 +++ llvm/tools/llvm-reduce/ReducerWorkItem.cpp| 11 --- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 llvm/test/tools/llvm-reduce/thinlto-preserve-uselistorder.ll diff --git a/llvm/test/tools/llvm-reduce/thinlto-preserve-uselistorder.ll b/llvm/test/tools/llvm-reduce/thinlto-preserve-uselistorder.ll new file mode 100644 index 0..2332f2d632911 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/thinlto-preserve-uselistorder.ll @@ -0,0 +1,19 @@ +; RUN: opt --thinlto-bc --thinlto-split-lto-unit %s -o %t.0 +; RUN: llvm-reduce -write-tmp-files-as-bitcode --delta-passes=instructions %t.0 -o %t.1 \ +; RUN: --test %python --test-arg %p/Inputs/llvm-dis-and-filecheck.py --test-arg llvm-dis --test-arg FileCheck --test-arg --check-prefix=INTERESTING --test-arg %s +; RUN: llvm-dis --preserve-ll-uselistorder %t.1 -o %t.2 +; RUN: FileCheck --check-prefix=RESULT %s < %t.2 + +define i32 @func(i32 %arg0, i32 %arg1) { +entry: + %add0 = add i32 %arg0, 0 + %add1 = add i32 %add0, 0 + %add2 = add i32 %add1, 0 + %add3 = add i32 %arg1, 0 + %add4 = add i32 %add2, %add3 + ret i32 %add4 +} + +; INTERESTING: uselistorder i32 0 +; RESULT: uselistorder i32 0, { 0, 2, 1 } +uselistorder i32 0, { 3, 2, 1, 0 } diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp index 8d2675c685038..9af2e5f5fdd23 100644 --- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp +++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp @@ -776,7 +776,11 @@ void ReducerWorkItem::readBitcode(MemoryBufferRef Data, LLVMContext &Ctx, } void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const { + const bool ShouldPreserveUseListOrder = true; + if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) { +// FIXME: This should not depend on the pass manager. There are hidden +// transforms that may happen inside ThinLTOBitcodeWriterPass PassBuilder PB; LoopAnalysisManager LAM; FunctionAnalysisManager FAM; @@ -788,7 +792,8 @@ void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const { PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM; -MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr)); +MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr, + ShouldPreserveUseListOrder)); MPM.run(*M, MAM); } else { std::unique_ptr Index; @@ -797,8 +802,8 @@ void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const { Index = std::make_unique( buildModuleSummaryIndex(*M, nullptr, &PSI)); } -WriteBitcodeToFile(getModule(), OutStream, - /*ShouldPreserveUseListOrder=*/true, Index.get()); +WriteBitcodeToFile(getModule(), OutStream, ShouldPreserveUseListOrder, + Index.get()); } } >From f324dce27a48741d8381843ba7478cf8f78b6c06 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 14 Apr 2025 16:19:11 +0200 Subject: [PATCH 2/2] Remove fixme --- llvm/tools/llvm-reduce/ReducerWorkItem.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp index 9af2e5f5fdd23..67da8bf1fd2bf 100644 --- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp +++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp @@ -779,8 +779,6 @@ void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const { const bool ShouldPreserveUseListOrder = true; if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) { -// FIXME: This should not depend on the pass manager. There are hidden -// transforms that may happen inside ThinLTOBitcodeWriterPass PassBuilder PB; LoopAnalysisManager LAM; FunctionAnalysisManager FAM; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm][IR] Treat memcmp and bcmp as libcalls (PR #135706)
efriedma-quic wrote: There are, currently, basically three different ways to supply libc which we support: - Dynamic linking: the libc isn't part of your program at all, it's part of the environment. You only have the abstract interface. - Static linking, no LTO of libc: the libc becomes part of your program at link-time: the linker lowers the libc abstraction into concrete calls. - -fno-builtins: The libc, excluding a small set of functions which are necessary for codegen, becomes part of your program at compile-time; once you're in LLVM IR, the abstraction is gone. To do "LTO of libc", you want something else... but you need to define what "something else" is. There needs to be a clearly delineated point at which libc implementation bits transition from an abstraction to concrete code. If your libc cooperates, that point can be different for different interfaces, but there still needs to be a specific point. You can't just blindly throw everything at the existing optimizer and hope for the best. If you say memcmp stays an abstraction past codegen, you're getting basically zero benefit from LTO'ing it, as far as I can tell: the caller is opaque to the callee, and the callee is opaque to the caller. At best. At worst, your code explodes because your memcmp implementation depends on runtime CPU detection code that runs startup, and LTO can't understand the dependency between the detection code and memcmp. So in essence, I feel like can't review this patch without a proposal that addresses where we're going overall. https://github.com/llvm/llvm-project/pull/135706 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20x: Revert "[ARM][ConstantIslands] Correct MinNoSplitDisp calculation (#114590)" (PR #135850)
https://github.com/alexrp milestoned https://github.com/llvm/llvm-project/pull/135850 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20x: Revert "[ARM][ConstantIslands] Correct MinNoSplitDisp calculation (#114590)" (PR #135850)
https://github.com/alexrp created https://github.com/llvm/llvm-project/pull/135850 This reverts commit e48916f615e0ad2b994b2b785d4fe1b8a98bc322. From fc9b72b1fc60dc0c556f6e146d735791df5c6581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 15 Apr 2025 22:32:34 +0200 Subject: [PATCH] Revert "[ARM][ConstantIslands] Correct MinNoSplitDisp calculation (#114590)" This reverts commit e48916f615e0ad2b994b2b785d4fe1b8a98bc322. --- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 3 +- .../Thumb2/constant-islands-no-split.mir | 165 -- 2 files changed, 1 insertion(+), 167 deletions(-) delete mode 100644 llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index e41e02a560db0..89eb49ed416ae 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1323,8 +1323,7 @@ bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, MachineBasicBlock *UserBB = U.MI->getParent(); BBInfoVector &BBInfo = BBUtils->getBBInfo(); const Align CPEAlign = getCPEAlign(U.CPEMI); - unsigned MinNoSplitDisp = - BBInfo[UserBB->getNumber()].postOffset(CPEAlign) - UserOffset; + unsigned MinNoSplitDisp = BBInfo[UserBB->getNumber()].postOffset(CPEAlign); if (CloserWater && MinNoSplitDisp > U.getMaxDisp() / 2) return false; for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();; diff --git a/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir b/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir deleted file mode 100644 index 9283ef14ca6cb..0 --- a/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir +++ /dev/null @@ -1,165 +0,0 @@ -# RUN: llc -mtriple=thumbv7-linux-gnueabihf -run-pass=arm-cp-islands -arm-constant-island-max-iteration=1 %s -o - | FileCheck %s | - ; ModuleID = 'constant-islands-new-island.ll' - source_filename = "constant-islands-new-island.ll" - target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" - target triple = "thumbv7-unknown-linux-gnueabihf" - - define void @test(i1 %tst) { - entry: -%0 = call i32 @llvm.arm.space(i32 2000, i32 undef) -br label %smallbb - - smallbb: ; preds = %entry -br i1 %tst, label %true, label %false - - true: ; preds = %false, %smallbb -%val = phi float [ 1.234500e+04, %smallbb ], [ undef, %false ] -%1 = call i32 @llvm.arm.space(i32 2000, i32 undef) -call void @bar(float %val) -ret void - - false:; preds = %smallbb -br label %true - } - - declare void @bar(float) - - ; Function Attrs: nounwind - declare i32 @llvm.arm.space(i32 immarg, i32) #0 - - attributes #0 = { nounwind } - -... -name:test -alignment: 2 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected:false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: true -isSSA: false -noVRegs: true -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: [] -liveins: - - { reg: '$r0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 16 - offsetAdjustment: 0 - maxAlignment:4 - adjustsStack:true - hasCalls:true - stackProtector: '' - functionContext: '' - maxCallFrameSize: 0 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: true - localFrameSize: 0 - savePoint: '' - restorePoint:'' -fixedStack: [] -stack: - - { id: 0, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 1, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 2, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 3, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, -
[llvm-branch-commits] [llvm] release/20x: Revert "[ARM][ConstantIslands] Correct MinNoSplitDisp calculation (#114590)" (PR #135850)
llvmbot wrote: @llvm/pr-subscribers-backend-arm Author: Alex Rรธnne Petersen (alexrp) Changes This reverts commit e48916f615e0ad2b994b2b785d4fe1b8a98bc322. --- Full diff: https://github.com/llvm/llvm-project/pull/135850.diff 2 Files Affected: - (modified) llvm/lib/Target/ARM/ARMConstantIslandPass.cpp (+1-2) - (removed) llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir (-165) ``diff diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index e41e02a560db0..89eb49ed416ae 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1323,8 +1323,7 @@ bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, MachineBasicBlock *UserBB = U.MI->getParent(); BBInfoVector &BBInfo = BBUtils->getBBInfo(); const Align CPEAlign = getCPEAlign(U.CPEMI); - unsigned MinNoSplitDisp = - BBInfo[UserBB->getNumber()].postOffset(CPEAlign) - UserOffset; + unsigned MinNoSplitDisp = BBInfo[UserBB->getNumber()].postOffset(CPEAlign); if (CloserWater && MinNoSplitDisp > U.getMaxDisp() / 2) return false; for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();; diff --git a/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir b/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir deleted file mode 100644 index 9283ef14ca6cb..0 --- a/llvm/test/CodeGen/Thumb2/constant-islands-no-split.mir +++ /dev/null @@ -1,165 +0,0 @@ -# RUN: llc -mtriple=thumbv7-linux-gnueabihf -run-pass=arm-cp-islands -arm-constant-island-max-iteration=1 %s -o - | FileCheck %s | - ; ModuleID = 'constant-islands-new-island.ll' - source_filename = "constant-islands-new-island.ll" - target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" - target triple = "thumbv7-unknown-linux-gnueabihf" - - define void @test(i1 %tst) { - entry: -%0 = call i32 @llvm.arm.space(i32 2000, i32 undef) -br label %smallbb - - smallbb: ; preds = %entry -br i1 %tst, label %true, label %false - - true: ; preds = %false, %smallbb -%val = phi float [ 1.234500e+04, %smallbb ], [ undef, %false ] -%1 = call i32 @llvm.arm.space(i32 2000, i32 undef) -call void @bar(float %val) -ret void - - false:; preds = %smallbb -br label %true - } - - declare void @bar(float) - - ; Function Attrs: nounwind - declare i32 @llvm.arm.space(i32 immarg, i32) #0 - - attributes #0 = { nounwind } - -... -name:test -alignment: 2 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected:false -failedISel: false -tracksRegLiveness: true -hasWinCFI: false -noPhis: true -isSSA: false -noVRegs: true -hasFakeUses: false -callsEHReturn: false -callsUnwindInit: false -hasEHCatchret: false -hasEHScopes: false -hasEHFunclets: false -isOutlined: false -debugInstrRef: false -failsVerification: false -tracksDebugUserValues: false -registers: [] -liveins: - - { reg: '$r0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 16 - offsetAdjustment: 0 - maxAlignment:4 - adjustsStack:true - hasCalls:true - stackProtector: '' - functionContext: '' - maxCallFrameSize: 0 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - isCalleeSavedInfoValid: true - localFrameSize: 0 - savePoint: '' - restorePoint:'' -fixedStack: [] -stack: - - { id: 0, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 1, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 2, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 3, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } -entry_values:[] -callSites: [] -debugValueSubstitutions: [] -constants: - - id: 0 -value: 'float 1.23
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
https://github.com/redstar edited https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/20x: Revert "[ARM][ConstantIslands] Correct MinNoSplitDisp calculation (#114590)" (PR #135850)
https://github.com/alexrp edited https://github.com/llvm/llvm-project/pull/135850 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From 8fee8cfe11c8856311e5e35aeeec8cc86bb063f1 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 28 +++- .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index f426c4ca9bc02..21733f2a2995d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1128,6 +1128,7 @@ void State::addInfoFor(BasicBlock &BB) { FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); break; // Enqueue the intrinsics to add extra info. +case Intrinsic::abs: case Intrinsic::umin: case Intrinsic::umax: case Intrinsic::smin: @@ -1141,7 +1142,6 @@ void State::addInfoFor(BasicBlock &BB) { if (!isGuaranteedNotToBePoison(&I)) break; [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1537,6 +1537,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1863,6 +1885,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 3 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + declare i32 @llvm.abs.i32(i32, i1 immarg) declare void @llvm.assume(i1) >From 08e8ec63bd1bacbbff468423481441e0c5e164b0 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 202
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to svusmmla (PR #135634)
https://github.com/momchil-velikov updated https://github.com/llvm/llvm-project/pull/135634 >From 5e91c2eb411cba43794fa7db918e88099885849e Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Thu, 10 Apr 2025 14:38:27 + Subject: [PATCH] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to `svusmmla` --- mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td | 95 +++ .../Transforms/LegalizeForLLVMExport.cpp | 4 + .../Dialect/ArmSVE/legalize-for-llvm.mlir | 12 +++ mlir/test/Dialect/ArmSVE/roundtrip.mlir | 11 +++ mlir/test/Target/LLVMIR/arm-sve.mlir | 12 +++ 5 files changed, 96 insertions(+), 38 deletions(-) diff --git a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td index 3a990f8464ef8..7385bb73b449a 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td +++ b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td @@ -147,11 +147,9 @@ class ScalableMaskedIOp, - AllTypesMatch<["acc", "dst"]>, - ]> { +def SdotOp : ArmSVE_Op<"sdot", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { let summary = "Vector-vector dot product and accumulate op"; let description = [{ SDOT: Signed integer addition of dot product. @@ -178,11 +176,9 @@ def SdotOp : ArmSVE_Op<"sdot", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def SmmlaOp : ArmSVE_Op<"smmla", -[Pure, -AllTypesMatch<["src1", "src2"]>, -AllTypesMatch<["acc", "dst"]>, - ]> { +def SmmlaOp : ArmSVE_Op<"smmla", [Pure, + AllTypesMatch<["src1", "src2"]>, + AllTypesMatch<["acc", "dst"]>]> { let summary = "Matrix-matrix multiply and accumulate op"; let description = [{ SMMLA: Signed integer matrix multiply-accumulate. @@ -210,11 +206,9 @@ def SmmlaOp : ArmSVE_Op<"smmla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def UdotOp : ArmSVE_Op<"udot", - [Pure, - AllTypesMatch<["src1", "src2"]>, - AllTypesMatch<["acc", "dst"]>, - ]> { +def UdotOp : ArmSVE_Op<"udot", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { let summary = "Vector-vector dot product and accumulate op"; let description = [{ UDOT: Unsigned integer addition of dot product. @@ -241,11 +235,9 @@ def UdotOp : ArmSVE_Op<"udot", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def UmmlaOp : ArmSVE_Op<"ummla", -[Pure, -AllTypesMatch<["src1", "src2"]>, -AllTypesMatch<["acc", "dst"]>, - ]> { +def UmmlaOp : ArmSVE_Op<"ummla", [Pure, + AllTypesMatch<["src1", "src2"]>, + AllTypesMatch<["acc", "dst"]>]> { let summary = "Matrix-matrix multiply and accumulate op"; let description = [{ UMMLA: Unsigned integer matrix multiply-accumulate. @@ -273,14 +265,42 @@ def UmmlaOp : ArmSVE_Op<"ummla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } +def UsmmlaOp : ArmSVE_Op<"usmmla", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { + let summary = "Matrix-matrix multiply and accumulate op"; + let description = [{ +USMMLA: Unsigned by signed integer matrix multiply-accumulate. + +The unsigned by signed integer matrix multiply-accumulate operation +multiplies the 2ร8 matrix of unsigned 8-bit integer values held +the first source vector by the 8ร2 matrix of signed 8-bit integer +values in the second source vector. The resulting 2ร2 widened 32-bit +integer matrix product is then added to the 32-bit integer matrix +accumulator. + +Source: +https://developer.arm.com/documentation/100987/ + }]; + // Supports (vector<16xi8>, vector<16xi8>) -> (vector<4xi32>) + let arguments = (ins + ScalableVectorOfLengthAndType<[4], [I32]>:$acc, + ScalableVectorOfLengthAndType<[16], [I8]>:$src1, + ScalableVectorOfLengthAndType<[16], [I8]>:$src2 + ); + let results = (outs ScalableVectorOfLengthAndType<[4], [I32]>:$dst); + let assemblyFormat = +"$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; +} + class SvboolTypeConstraint : TypesMatchWith< "expected corresponding svbool type widened to [16]xi1", lhsArg, rhsArg, "VectorType(VectorType::Builder(::llvm::cast($_self)).setDim(::llvm::cast($_self).getRank() - 1, 16))">; def ConvertFromSvboolOp : ArmSVE_Op<"convert_from_svbool", -[Pure, SvboolTypeConstraint<"result", "source">]> -{ +
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
@@ -294,4 +294,13 @@ def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; // VIS3 instruction patterns. let Predicates = [HasVIS3] in { def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 ยง7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), +(ANDrr (SRAXri $rhs, 63), $lhs)))>; s-barannikov wrote: I've just realized than on my target there is the same issue (two additional muls). I solved it by adding a simple DAG combiner optimization (`setTargetDAGCombine(ISD::MUL)`). As I noted in the other PR, doing longer expansions earlier opens opportunities for other optimizations. This is how it looks like: ```C++ SDValue <...>TargetLowering::combineMUL(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); EVT VT = N->getValueType(0); SDLoc DL(N); // (mul X, sign_mask) -> (and (sub 0, X), sign_mask). if (DAG.ComputeNumSignBits(LHS) == VT.getFixedSizeInBits()) { SDValue Neg = DAG.getNegative(RHS, DL, VT); return DAG.getNode(ISD::AND, DL, VT, LHS, Neg); } if (DAG.ComputeNumSignBits(RHS) == VT.getFixedSizeInBits()) { SDValue Neg = DAG.getNegative(LHS, DL, VT); return DAG.getNode(ISD::AND, DL, VT, RHS, Neg); } return SDValue(); } ``` This could be done by the generic DAG combiner, but it replaces one instruction with two, so I didn't try upstream it. Can you try it with MULHS set to Expand? https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From 8fee8cfe11c8856311e5e35aeeec8cc86bb063f1 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 28 +++- .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index f426c4ca9bc02..21733f2a2995d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1128,6 +1128,7 @@ void State::addInfoFor(BasicBlock &BB) { FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); break; // Enqueue the intrinsics to add extra info. +case Intrinsic::abs: case Intrinsic::umin: case Intrinsic::umax: case Intrinsic::smin: @@ -1141,7 +1142,6 @@ void State::addInfoFor(BasicBlock &BB) { if (!isGuaranteedNotToBePoison(&I)) break; [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1537,6 +1537,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1863,6 +1885,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 3 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + declare i32 @llvm.abs.i32(i32, i1 immarg) declare void @llvm.assume(i1) >From 08e8ec63bd1bacbbff468423481441e0c5e164b0 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 202
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to svusmmla (PR #135634)
https://github.com/momchil-velikov updated https://github.com/llvm/llvm-project/pull/135634 >From 5e91c2eb411cba43794fa7db918e88099885849e Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Thu, 10 Apr 2025 14:38:27 + Subject: [PATCH] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to `svusmmla` --- mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td | 95 +++ .../Transforms/LegalizeForLLVMExport.cpp | 4 + .../Dialect/ArmSVE/legalize-for-llvm.mlir | 12 +++ mlir/test/Dialect/ArmSVE/roundtrip.mlir | 11 +++ mlir/test/Target/LLVMIR/arm-sve.mlir | 12 +++ 5 files changed, 96 insertions(+), 38 deletions(-) diff --git a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td index 3a990f8464ef8..7385bb73b449a 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td +++ b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td @@ -147,11 +147,9 @@ class ScalableMaskedIOp, - AllTypesMatch<["acc", "dst"]>, - ]> { +def SdotOp : ArmSVE_Op<"sdot", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { let summary = "Vector-vector dot product and accumulate op"; let description = [{ SDOT: Signed integer addition of dot product. @@ -178,11 +176,9 @@ def SdotOp : ArmSVE_Op<"sdot", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def SmmlaOp : ArmSVE_Op<"smmla", -[Pure, -AllTypesMatch<["src1", "src2"]>, -AllTypesMatch<["acc", "dst"]>, - ]> { +def SmmlaOp : ArmSVE_Op<"smmla", [Pure, + AllTypesMatch<["src1", "src2"]>, + AllTypesMatch<["acc", "dst"]>]> { let summary = "Matrix-matrix multiply and accumulate op"; let description = [{ SMMLA: Signed integer matrix multiply-accumulate. @@ -210,11 +206,9 @@ def SmmlaOp : ArmSVE_Op<"smmla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def UdotOp : ArmSVE_Op<"udot", - [Pure, - AllTypesMatch<["src1", "src2"]>, - AllTypesMatch<["acc", "dst"]>, - ]> { +def UdotOp : ArmSVE_Op<"udot", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { let summary = "Vector-vector dot product and accumulate op"; let description = [{ UDOT: Unsigned integer addition of dot product. @@ -241,11 +235,9 @@ def UdotOp : ArmSVE_Op<"udot", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } -def UmmlaOp : ArmSVE_Op<"ummla", -[Pure, -AllTypesMatch<["src1", "src2"]>, -AllTypesMatch<["acc", "dst"]>, - ]> { +def UmmlaOp : ArmSVE_Op<"ummla", [Pure, + AllTypesMatch<["src1", "src2"]>, + AllTypesMatch<["acc", "dst"]>]> { let summary = "Matrix-matrix multiply and accumulate op"; let description = [{ UMMLA: Unsigned integer matrix multiply-accumulate. @@ -273,14 +265,42 @@ def UmmlaOp : ArmSVE_Op<"ummla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } +def UsmmlaOp : ArmSVE_Op<"usmmla", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { + let summary = "Matrix-matrix multiply and accumulate op"; + let description = [{ +USMMLA: Unsigned by signed integer matrix multiply-accumulate. + +The unsigned by signed integer matrix multiply-accumulate operation +multiplies the 2ร8 matrix of unsigned 8-bit integer values held +the first source vector by the 8ร2 matrix of signed 8-bit integer +values in the second source vector. The resulting 2ร2 widened 32-bit +integer matrix product is then added to the 32-bit integer matrix +accumulator. + +Source: +https://developer.arm.com/documentation/100987/ + }]; + // Supports (vector<16xi8>, vector<16xi8>) -> (vector<4xi32>) + let arguments = (ins + ScalableVectorOfLengthAndType<[4], [I32]>:$acc, + ScalableVectorOfLengthAndType<[16], [I8]>:$src1, + ScalableVectorOfLengthAndType<[16], [I8]>:$src2 + ); + let results = (outs ScalableVectorOfLengthAndType<[4], [I32]>:$dst); + let assemblyFormat = +"$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; +} + class SvboolTypeConstraint : TypesMatchWith< "expected corresponding svbool type widened to [16]xi1", lhsArg, rhsArg, "VectorType(VectorType::Builder(::llvm::cast($_self)).setDim(::llvm::cast($_self).getRank() - 1, 16))">; def ConvertFromSvboolOp : ArmSVE_Op<"convert_from_svbool", -[Pure, SvboolTypeConstraint<"result", "source">]> -{ +
[llvm-branch-commits] [SPARC] Use addxccc to do multiword addition when we have VIS3 (PR #135713)
@@ -1737,6 +1737,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SUBC, MVT::i32, Legal); setOperationAction(ISD::SUBE, MVT::i32, Legal); + if (Subtarget->isVIS3()) { +setOperationAction(ISD::ADDC, MVT::i64, Legal); +setOperationAction(ISD::ADDE, MVT::i64, Legal); koachan wrote: Will do, but I think it's better to leave the patch as-is for now and do the switch in another patch. https://github.com/llvm/llvm-project/pull/135713 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] Silence -Wcast-function-type warnings on idiomatic Windows code (#135โฆ (PR #135798)
https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/135798 โฆ660) On Windows, GetProcAddress() is the API used to dynamically load function pointers (similar to dlsym on Linux). This API returns a function pointer (a typedef named FARPROC), which means that casting from the call to the eventual correct type is technically a function type mismatch on the cast. However, because this is idiomatic code on Windows, we should accept it unless -Wcast-function-type-strict is passed. This was brought up in post-commit review feedback on https://github.com/llvm/llvm-project/pull/86131 >From 754c032f3ccea10c14c3a2789b0e3ada6cc4c914 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 15 Apr 2025 11:19:19 -0400 Subject: [PATCH] Silence -Wcast-function-type warnings on idiomatic Windows code (#135660) On Windows, GetProcAddress() is the API used to dynamically load function pointers (similar to dlsym on Linux). This API returns a function pointer (a typedef named FARPROC), which means that casting from the call to the eventual correct type is technically a function type mismatch on the cast. However, because this is idiomatic code on Windows, we should accept it unless -Wcast-function-type-strict is passed. This was brought up in post-commit review feedback on https://github.com/llvm/llvm-project/pull/86131 --- clang/docs/ReleaseNotes.rst | 10 ++ clang/lib/Sema/SemaCast.cpp | 23 clang/test/Sema/warn-cast-function-type-win.c | 36 +++ 3 files changed, 69 insertions(+) create mode 100644 clang/test/Sema/warn-cast-function-type-win.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f4befc242f28b..b8f26ec9a5447 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -694,6 +694,16 @@ Improvements to Clang's diagnostics match a template template parameter, in terms of the C++17 relaxed matching rules instead of the old ones. +- No longer diagnosing idiomatic function pointer casts on Windows under + ``-Wcast-function-type-mismatch`` (which is enabled by ``-Wextra``). Clang + would previously warn on this construct, but will no longer do so on Windows: + + .. code-block:: c + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +HMODULE Lib = LoadLibrary("kernel32"); +PGNSI FnPtr = (PGNSI)GetProcAddress(Lib, "GetNativeSystemInfo"); + - Don't emit duplicated dangling diagnostics. (#GH93386). - Improved diagnostic when trying to befriend a concept. (#GH45182). diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 54bc52fa2ac40..d0d44e8899133 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1151,10 +1151,33 @@ static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, return false; }; + auto IsFarProc = [](const FunctionType *T) { +// The definition of FARPROC depends on the platform in terms of its return +// type, which could be int, or long long, etc. We'll look for a source +// signature for: (*)() and call that "close enough" to +// FARPROC to be sufficient to silence the diagnostic. This is similar to +// how we allow casts between function pointers and void * for supporting +// dlsym. +// Note: we could check for __stdcall on the function pointer as well, but +// that seems like splitting hairs. +if (!T->getReturnType()->isIntegerType()) + return false; +if (const auto *PT = T->getAs()) + return !PT->isVariadic() && PT->getNumParams() == 0; +return true; + }; + // Skip if either function type is void(*)(void) if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy)) return 0; + // On Windows, GetProcAddress() returns a FARPROC, which is a typedef for a + // function pointer type (with no prototype, in C). We don't want to diagnose + // this case so we don't diagnose idiomatic code on Windows. + if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() && + IsFarProc(SrcFTy)) +return 0; + // Check return type. if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(), Self.Context)) diff --git a/clang/test/Sema/warn-cast-function-type-win.c b/clang/test/Sema/warn-cast-function-type-win.c new file mode 100644 index 0..4e7ba33b258d8 --- /dev/null +++ b/clang/test/Sema/warn-cast-function-type-win.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=linux +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type
[llvm-branch-commits] [clang] Silence -Wcast-function-type warnings on idiomatic Windows code (#135โฆ (PR #135798)
llvmbot wrote: @llvm/pr-subscribers-platform-windows Author: Aaron Ballman (AaronBallman) Changes โฆ660) On Windows, GetProcAddress() is the API used to dynamically load function pointers (similar to dlsym on Linux). This API returns a function pointer (a typedef named FARPROC), which means that casting from the call to the eventual correct type is technically a function type mismatch on the cast. However, because this is idiomatic code on Windows, we should accept it unless -Wcast-function-type-strict is passed. This was brought up in post-commit review feedback on https://github.com/llvm/llvm-project/pull/86131 --- Full diff: https://github.com/llvm/llvm-project/pull/135798.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+10) - (modified) clang/lib/Sema/SemaCast.cpp (+23) - (added) clang/test/Sema/warn-cast-function-type-win.c (+36) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f4befc242f28b..b8f26ec9a5447 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -694,6 +694,16 @@ Improvements to Clang's diagnostics match a template template parameter, in terms of the C++17 relaxed matching rules instead of the old ones. +- No longer diagnosing idiomatic function pointer casts on Windows under + ``-Wcast-function-type-mismatch`` (which is enabled by ``-Wextra``). Clang + would previously warn on this construct, but will no longer do so on Windows: + + .. code-block:: c + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +HMODULE Lib = LoadLibrary("kernel32"); +PGNSI FnPtr = (PGNSI)GetProcAddress(Lib, "GetNativeSystemInfo"); + - Don't emit duplicated dangling diagnostics. (#GH93386). - Improved diagnostic when trying to befriend a concept. (#GH45182). diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 54bc52fa2ac40..d0d44e8899133 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1151,10 +1151,33 @@ static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, return false; }; + auto IsFarProc = [](const FunctionType *T) { +// The definition of FARPROC depends on the platform in terms of its return +// type, which could be int, or long long, etc. We'll look for a source +// signature for: (*)() and call that "close enough" to +// FARPROC to be sufficient to silence the diagnostic. This is similar to +// how we allow casts between function pointers and void * for supporting +// dlsym. +// Note: we could check for __stdcall on the function pointer as well, but +// that seems like splitting hairs. +if (!T->getReturnType()->isIntegerType()) + return false; +if (const auto *PT = T->getAs()) + return !PT->isVariadic() && PT->getNumParams() == 0; +return true; + }; + // Skip if either function type is void(*)(void) if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy)) return 0; + // On Windows, GetProcAddress() returns a FARPROC, which is a typedef for a + // function pointer type (with no prototype, in C). We don't want to diagnose + // this case so we don't diagnose idiomatic code on Windows. + if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() && + IsFarProc(SrcFTy)) +return 0; + // Check return type. if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(), Self.Context)) diff --git a/clang/test/Sema/warn-cast-function-type-win.c b/clang/test/Sema/warn-cast-function-type-win.c new file mode 100644 index 0..4e7ba33b258d8 --- /dev/null +++ b/clang/test/Sema/warn-cast-function-type-win.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=linux +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=linux,linux-cpp +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wcast-function-type-strict -x c++ -verify=strict +// windows-no-diagnostics + +// On Windows targets, this is expected to compile fine, and on non-Windows +// targets, this should diagnose the mismatch. This is to allow for idiomatic +// use of GetProcAddress, similar to what we do for dlsym. On non-Windows +// targets, this should be diagnosed. +typedef int (*FARPROC1)(); +typedef unsigned long long (*FARPROC2)(); + +FARPROC1 GetProcAddress1(void); +FARPROC2 GetProcAddress2(void); + +typedef int (*test1_type)(int); +typedef float(*test2_type)(); + +void test(void) { + // This does not diagnose on Linux in C mode because FARPROC1
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,145 @@ +//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/MC/MCSectionGOFF.h" +#include "llvm/BinaryFormat/GOFF.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) { + if (Rmode != GOFF::ESD_RMODE_None) { +OS << "RMODE" << (UseParenthesis ? '(' : ' '); +switch (Rmode) { +case GOFF::ESD_RMODE_24: + OS << "24"; + break; +case GOFF::ESD_RMODE_31: + OS << "31"; + break; +case GOFF::ESD_RMODE_64: + OS << "64"; + break; +case GOFF::ESD_RMODE_None: + break; +} +if (UseParenthesis) + OS << ')'; + } +} + +void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName, + bool EmitAmodeAndRmode, GOFF::ESDAmode Amode, + GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment, + GOFF::ESDLoadingBehavior LoadBehavior, + GOFF::ESDExecutable Executable, bool IsReadOnly, + StringRef PartName) { + if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) { +OS << ParentName << " AMODE "; redstar wrote: > I think we should actually emit the AMODE for that instead. I (or Tony) will do when emitting the labels. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754 >From c48f67f690abb727682c988341e743740e962576 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 15:00:58 +0800 Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints --- .../Scalar/ConstraintElimination.cpp | 28 +++- .../Transforms/ConstraintElimination/abs.ll | 43 +++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index f426c4ca9bc02..21733f2a2995d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1128,6 +1128,7 @@ void State::addInfoFor(BasicBlock &BB) { FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); break; // Enqueue the intrinsics to add extra info. +case Intrinsic::abs: case Intrinsic::umin: case Intrinsic::umax: case Intrinsic::smin: @@ -1141,7 +1142,6 @@ void State::addInfoFor(BasicBlock &BB) { if (!isGuaranteedNotToBePoison(&I)) break; [[fallthrough]]; -case Intrinsic::abs: case Intrinsic::uadd_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; @@ -1537,6 +1537,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic"); + Value *Op = I->getOperand(0); + if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +I->replaceAllUsesWith(Op); +ToRemove.push_back(I); +return true; + } + if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0), + I, Info) + .value_or(false)) { +IRBuilder<> Builder(I->getParent(), I->getIterator()); +I->replaceAllUsesWith(Builder.CreateNeg(Op)); +ToRemove.push_back(I); +return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1863,6 +1885,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); else llvm_unreachable("Unexpected intrinsic."); + } else if (auto *II = dyn_cast(Inst)) { +if (II->getIntrinsicID() == Intrinsic::abs) { + Changed |= checkAndReplaceAbs(II, Info, ToRemove); +} } continue; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..32f686a6fcb8f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -159,5 +159,48 @@ define i1 @abs_is_nonnegative_constant_arg() { ret i1 %cmp } +define i64 @abs_assume_nonnegative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_nonnegative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp sge i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +define i64 @abs_assume_negative(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_negative( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 0 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + +; Negative test +define i64 @abs_assume_unrelated(i64 %arg) { +; CHECK-LABEL: define i64 @abs_assume_unrelated( +; CHECK-SAME: i64 [[ARG:%.*]]) { +; CHECK-NEXT:[[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3 +; CHECK-NEXT:call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT:[[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false) +; CHECK-NEXT:ret i64 [[ABS]] +; + %precond = icmp slt i64 %arg, 3 + call void @llvm.assume(i1 %precond) + %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false) + ret i64 %abs +} + declare i32 @llvm.abs.i32(i32, i1 immarg) declare void @llvm.assume(i1) >From bad3538ff3f466649fc69a3dcb2b84bb2093c23d Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 202
[llvm-branch-commits] [llvm] [llvm][IR] Treat memcmp and bcmp as libcalls (PR #135706)
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/135706 >From 4b8f422ee979e6063e553f8a5bc292c5a11e13b4 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Mon, 14 Apr 2025 08:25:15 -0700 Subject: [PATCH] [llvm][IR] Treat memcmp and bcmp as libcalls Since the backend may emit calls to these functions, they should be treated like other libcalls. If we don't, then it is possible to have their definitions removed during LTO because they are dead, only to have a later transform introduce calls to them. See https://discourse.llvm.org/t/rfc-addressing-deficiencies-in-llvm-s-lto-implementation/84999 for more information. --- llvm/include/llvm/IR/RuntimeLibcalls.def | 2 ++ llvm/test/LTO/Resolution/X86/bcmp-libcall.ll | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index 2545aebc73391..2c72bc8c012cc 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -513,6 +513,8 @@ HANDLE_LIBCALL(UO_PPCF128, "__gcc_qunord") HANDLE_LIBCALL(MEMCPY, "memcpy") HANDLE_LIBCALL(MEMMOVE, "memmove") HANDLE_LIBCALL(MEMSET, "memset") +HANDLE_LIBCALL(MEMCMP, "memcmp") +HANDLE_LIBCALL(BCMP, "bcmp") // DSEPass can emit calloc if it finds a pair of malloc/memset HANDLE_LIBCALL(CALLOC, "calloc") HANDLE_LIBCALL(BZERO, nullptr) diff --git a/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll b/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll index b4e526f83e60f..48ea6291308ab 100644 --- a/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll +++ b/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll @@ -26,9 +26,8 @@ define i1 @foo(ptr %0, [2 x i32] %1) { ; CHECK: declare i32 @memcmp(ptr, ptr, i32) declare i32 @memcmp(ptr, ptr, i32) -;; Ensure bcmp is removed from module. Follow up patches can address this. -; CHECK-NOT: declare{{.*}}i32 @bcmp -; CHECK-NOT: define{{.*}}i32 @bcmp +;; Ensure bcmp is not removed from module. +; CHECK: define{{.*}}i32 @bcmp define i32 @bcmp(ptr %0, ptr %1, i32 %2) { ret i32 0 } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm][IR] Treat memcmp and bcmp as libcalls (PR #135706)
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/135706 >From 4b8f422ee979e6063e553f8a5bc292c5a11e13b4 Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Mon, 14 Apr 2025 08:25:15 -0700 Subject: [PATCH] [llvm][IR] Treat memcmp and bcmp as libcalls Since the backend may emit calls to these functions, they should be treated like other libcalls. If we don't, then it is possible to have their definitions removed during LTO because they are dead, only to have a later transform introduce calls to them. See https://discourse.llvm.org/t/rfc-addressing-deficiencies-in-llvm-s-lto-implementation/84999 for more information. --- llvm/include/llvm/IR/RuntimeLibcalls.def | 2 ++ llvm/test/LTO/Resolution/X86/bcmp-libcall.ll | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index 2545aebc73391..2c72bc8c012cc 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -513,6 +513,8 @@ HANDLE_LIBCALL(UO_PPCF128, "__gcc_qunord") HANDLE_LIBCALL(MEMCPY, "memcpy") HANDLE_LIBCALL(MEMMOVE, "memmove") HANDLE_LIBCALL(MEMSET, "memset") +HANDLE_LIBCALL(MEMCMP, "memcmp") +HANDLE_LIBCALL(BCMP, "bcmp") // DSEPass can emit calloc if it finds a pair of malloc/memset HANDLE_LIBCALL(CALLOC, "calloc") HANDLE_LIBCALL(BZERO, nullptr) diff --git a/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll b/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll index b4e526f83e60f..48ea6291308ab 100644 --- a/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll +++ b/llvm/test/LTO/Resolution/X86/bcmp-libcall.ll @@ -26,9 +26,8 @@ define i1 @foo(ptr %0, [2 x i32] %1) { ; CHECK: declare i32 @memcmp(ptr, ptr, i32) declare i32 @memcmp(ptr, ptr, i32) -;; Ensure bcmp is removed from module. Follow up patches can address this. -; CHECK-NOT: declare{{.*}}i32 @bcmp -; CHECK-NOT: define{{.*}}i32 @bcmp +;; Ensure bcmp is not removed from module. +; CHECK: define{{.*}}i32 @bcmp define i32 @bcmp(ptr %0, ptr %1, i32 %2) { ret i32 0 } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/20.x: [Clang] Fix a lambda pattern comparison mismatch after ecc7e6ce4 (#133863) (PR #134194)
zyn0217 wrote: It's been 11 days so I think this is mature enough - @erichkeane WDYT? https://github.com/llvm/llvm-project/pull/134194 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use addxccc to do multiword addition when we have VIS3 (PR #135713)
https://github.com/koachan created https://github.com/llvm/llvm-project/pull/135713 None ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use op-then-neg instructions when we have VIS3 (PR #135717)
https://github.com/koachan edited https://github.com/llvm/llvm-project/pull/135717 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] release/20.x: [X86][AVX10] Remove VAES and VPCLMULQDQ feature from AVX10.1 (#135489) (PR #135577)
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/135577 Backport ebba554a3211b0b98d3ae33ba70f9d6ceaab6ad4 Requested by: @phoebewang >From 68e697347eac8c44c577df4e1bfeba3177d37ce4 Mon Sep 17 00:00:00 2001 From: Phoebe Wang Date: Mon, 14 Apr 2025 08:54:10 +0800 Subject: [PATCH] [X86][AVX10] Remove VAES and VPCLMULQDQ feature from AVX10.1 (#135489) According to SDM, they require both VAES/VPCLMULQDQ and AVX10.1 CPUID bits. Fixes: #135394 (cherry picked from commit ebba554a3211b0b98d3ae33ba70f9d6ceaab6ad4) --- clang/test/CodeGen/attr-target-x86.c | 8 llvm/lib/Target/X86/X86.td| 2 +- llvm/lib/TargetParser/X86TargetParser.cpp | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c index c92aad633082f..e5067c1c3b075 100644 --- a/clang/test/CodeGen/attr-target-x86.c +++ b/clang/test/CodeGen/attr-target-x86.c @@ -56,7 +56,7 @@ void f_default2(void) { __attribute__((target("avx, sse4.2, arch= ivybridge"))) void f_avx_sse4_2_ivybridge_2(void) {} -// CHECK: [[f_no_aes_ivybridge]] = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-amx-avx512,-avx10.1-256,-avx10.1-512,-avx10.2-256,-avx10.2-512,-vaes" +// CHECK: [[f_no_aes_ivybridge]] = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes" __attribute__((target("no-aes, arch=ivybridge"))) void f_no_aes_ivybridge(void) {} @@ -98,11 +98,11 @@ void f_x86_64_v3(void) {} __attribute__((target("arch=x86-64-v4"))) void f_x86_64_v4(void) {} -// CHECK: [[f_avx10_1_256]] = {{.*}}"target-cpu"="i686" "target-features"="+aes,+avx,+avx10.1-256,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+f16c,+fma,+mmx,+pclmul,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,-amx-avx512,-avx10.1-512,-avx10.2-512,-evex512" +// CHECK: [[f_avx10_1_256]] = {{.*}}"target-cpu"="i686" "target-features"="+avx,+avx10.1-256,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,-amx-avx512,-avx10.1-512,-avx10.2-512,-evex512" __attribute__((target("avx10.1-256"))) void f_avx10_1_256(void) {} -// CHECK: [[f_avx10_1_512]] = {{.*}}"target-cpu"="i686" "target-features"="+aes,+avx,+avx10.1-256,+avx10.1-512,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+evex512,+f16c,+fma,+mmx,+pclmul,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave" +// CHECK: [[f_avx10_1_512]] = {{.*}}"target-cpu"="i686" "target-features"="+avx,+avx10.1-256,+avx10.1-512,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+evex512,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" __attribute__((target("avx10.1-512"))) void f_avx10_1_512(void) {} @@ -112,4 +112,4 @@ void f_prefer_256_bit(void) {} // CHECK: [[f_no_prefer_256_bit]] = {{.*}}"target-features"="{{.*}}-prefer-256-bit __attribute__((target("no-prefer-256-bit"))) -void f_no_prefer_256_bit(void) {} \ No newline at end of file +void f_no_prefer_256_bit(void) {} diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 38761e1fd7eec..577428cad6d61 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -338,7 +338,7 @@ def FeatureAVX10_1 : SubtargetFeature<"avx10.1-256", "HasAVX10_1", "true", "Support AVX10.1 up to 256-bit instruction", [FeatureCDI, FeatureVBMI, FeatureIFMA, FeatureVNNI, FeatureBF16, FeatureVPOPCNTDQ, FeatureVBMI2, FeatureBITALG, - FeatureVAES, FeatureVPCLMULQDQ, FeatureFP16]>; + FeatureFP16]>; def FeatureAVX10_1_512 : SubtargetFeature<"avx10.1-512", "HasAVX10_1_512", "true", "Support AVX10.1 up to 512-bit instruction", [FeatureAVX10_1, FeatureEVEX512]>; diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp index e4b7ed7cf9b61..2ae6dd6b3d1ef 100644 --
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add an ArmSVE dialect operation which maps to svusmmla (PR #135634)
llvmbot wrote: @llvm/pr-subscribers-mlir Author: Momchil Velikov (momchil-velikov) Changes Supersedes https://github.com/llvm/llvm-project/pull/135358 --- Full diff: https://github.com/llvm/llvm-project/pull/135634.diff 5 Files Affected: - (modified) mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td (+32) - (modified) mlir/lib/Dialect/ArmSVE/Transforms/LegalizeForLLVMExport.cpp (+4) - (modified) mlir/test/Dialect/ArmSVE/legalize-for-llvm.mlir (+12) - (modified) mlir/test/Dialect/ArmSVE/roundtrip.mlir (+11) - (modified) mlir/test/Target/LLVMIR/arm-sve.mlir (+12) ``diff diff --git a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td index 1a59062ccc93d..da2a8f89b4cfd 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td +++ b/mlir/include/mlir/Dialect/ArmSVE/IR/ArmSVE.td @@ -273,6 +273,34 @@ def UmmlaOp : ArmSVE_Op<"ummla", "$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; } +def UsmmlaOp : ArmSVE_Op<"usmmla", [Pure, +AllTypesMatch<["src1", "src2"]>, +AllTypesMatch<["acc", "dst"]>]> { + let summary = "Matrix-matrix multiply and accumulate op"; + let description = [{ +USMMLA: Unsigned by signed integer matrix multiply-accumulate. + +The unsigned by signed integer matrix multiply-accumulate operation +multiplies the 2ร8 matrix of unsigned 8-bit integer values held +the first source vector by the 8ร2 matrix of signed 8-bit integer +values in the second source vector. The resulting 2ร2 widened 32-bit +integer matrix product is then added to the 32-bit integer matrix +accumulator. + +Source: +https://developer.arm.com/documentation/100987/ + }]; + // Supports (vector<16xi8>, vector<16xi8>) -> (vector<4xi32>) + let arguments = (ins + ScalableVectorOfLengthAndType<[4], [I32]>:$acc, + ScalableVectorOfLengthAndType<[16], [I8]>:$src1, + ScalableVectorOfLengthAndType<[16], [I8]>:$src2 + ); + let results = (outs ScalableVectorOfLengthAndType<[4], [I32]>:$dst); + let assemblyFormat = +"$acc `,` $src1 `,` $src2 attr-dict `:` type($src1) `to` type($dst)"; +} + class SvboolTypeConstraint : TypesMatchWith< "expected corresponding svbool type widened to [16]xi1", lhsArg, rhsArg, @@ -568,6 +596,10 @@ def SmmlaIntrOp : ArmSVE_IntrBinaryOverloadedOp<"smmla">, Arguments<(ins AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank)>; +def UsmmlaIntrOp : + ArmSVE_IntrBinaryOverloadedOp<"usmmla">, + Arguments<(ins AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank)>; + def SdotIntrOp : ArmSVE_IntrBinaryOverloadedOp<"sdot">, Arguments<(ins AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank, AnyScalableVectorOfAnyRank)>; diff --git a/mlir/lib/Dialect/ArmSVE/Transforms/LegalizeForLLVMExport.cpp b/mlir/lib/Dialect/ArmSVE/Transforms/LegalizeForLLVMExport.cpp index fe13ed03356b2..b1846e15196fc 100644 --- a/mlir/lib/Dialect/ArmSVE/Transforms/LegalizeForLLVMExport.cpp +++ b/mlir/lib/Dialect/ArmSVE/Transforms/LegalizeForLLVMExport.cpp @@ -24,6 +24,7 @@ using SdotOpLowering = OneToOneConvertToLLVMPattern; using SmmlaOpLowering = OneToOneConvertToLLVMPattern; using UdotOpLowering = OneToOneConvertToLLVMPattern; using UmmlaOpLowering = OneToOneConvertToLLVMPattern; +using UsmmlaOpLowering = OneToOneConvertToLLVMPattern; using DupQLaneLowering = OneToOneConvertToLLVMPattern; using ScalableMaskedAddIOpLowering = @@ -194,6 +195,7 @@ void mlir::populateArmSVELegalizeForLLVMExportPatterns( SmmlaOpLowering, UdotOpLowering, UmmlaOpLowering, + UsmmlaOpLowering, DupQLaneLowering, ScalableMaskedAddIOpLowering, ScalableMaskedAddFOpLowering, @@ -222,6 +224,7 @@ void mlir::configureArmSVELegalizeForExportTarget( SmmlaIntrOp, UdotIntrOp, UmmlaIntrOp, +UsmmlaIntrOp, DupQLaneIntrOp, ScalableMaskedAddIIntrOp, ScalableMaskedAddFIntrOp, @@ -242,6 +245,7 @@ void mlir::configureArmSVELegalizeForExportTarget( SmmlaOp, UdotOp, UmmlaOp, + UsmmlaOp, DupQLaneOp, ScalableMaskedAddIOp, ScalableMaskedAddFOp, diff --git a/mlir/test/Dialect/ArmSVE/legalize-for-llvm.mlir b/mlir/test/Dialect/ArmSVE/legalize-for-llvm.mlir index 5d044517e0ea8..47587aa26506c 100644 --- a/mlir/test/Dialect/ArmSVE/legalize-for-llvm.mlir +++ b/mlir/test/Dialect/ArmSVE/legalize-for-llvm.mlir @@ -48,6 +48,18 @@ func.func @arm_sve_ummla(%a: vector<[16]xi8>, // - +func.func @arm_sve_usmmla(%a: vector<[16]xi8>, +%
[llvm-branch-commits] [llvm] [HLSL] Adding support for Root Constants in LLVM Metadata (PR #135085)
@@ -24,7 +24,11 @@ namespace llvm { namespace dxil { -enum class RootSignatureElementKind { Error = 0, RootFlags = 1 }; +enum class RootSignatureElementKind { inbelic wrote: What is the reason to define this instead of just using `dxbc::RootParameterType`. They seem to map to the same value and we are already using it in `DXILRootSignature.cpp` https://github.com/llvm/llvm-project/pull/135085 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [Github][CI] Upload .ninja_log as an artifact (PR #135539)
https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/135539 >From 109923e35d854d63faa5b9599f5fd128bcfe5c79 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sun, 13 Apr 2025 11:26:06 + Subject: [PATCH 1/3] testing Created using spr 1.3.4 --- .ci/monolithic-linux.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index 6461c9d40ad59..8c1ad5d80da51 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -34,6 +34,7 @@ function at-exit { mkdir -p artifacts ccache --print-stats > artifacts/ccache_stats.txt cp "${BUILD_DIR}"/.ninja_log artifacts/.ninja_log + ls artifacts/ # If building fails there will be no results files. shopt -s nullglob >From 78c42b3aed24e533d53b2f701f5a0abd5f611e2a Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sun, 13 Apr 2025 11:43:16 + Subject: [PATCH 2/3] cleanup Created using spr 1.3.4 --- flang/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 236b4644404ec..76eb13295eb07 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -1,4 +1,3 @@ -# testing cmake_minimum_required(VERSION 3.20.0) set(LLVM_SUBPROJECT_TITLE "Flang") >From cb1924f997f4e35014df8bc072f038992b7a6bca Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Mon, 14 Apr 2025 07:36:51 + Subject: [PATCH 3/3] fix Created using spr 1.3.4 --- .ci/monolithic-linux.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index 8c1ad5d80da51..6461c9d40ad59 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -34,7 +34,6 @@ function at-exit { mkdir -p artifacts ccache --print-stats > artifacts/ccache_stats.txt cp "${BUILD_DIR}"/.ninja_log artifacts/.ninja_log - ls artifacts/ # If building fails there will be no results files. shopt -s nullglob ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
@@ -294,4 +294,13 @@ def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; // VIS3 instruction patterns. let Predicates = [HasVIS3] in { def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 ยง7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), +(ANDrr (SRAXri $rhs, 63), $lhs)))>; koachan wrote: It works, in that it cuts down on the number of multiplies, but it still seems to produce more instructions than manual matching (e.g in `signed_multiply_extend`): ``` ; VIS3-LABEL: signed_multiply_extend: ; VIS3: ! %bb.0: ; VIS3-NEXT:srax %o0, 63, %o2 ; VIS3-NEXT:srax %o1, 63, %o3 ; VIS3-NEXT:umulxhi %o1, %o0, %o4 ; VIS3-NEXT:sub %g0, %o1, %o5 ; VIS3-NEXT:and %o2, %o5, %o2 ; VIS3-NEXT:add %o4, %o2, %o2 ; VIS3-NEXT:sub %g0, %o0, %o4 ; VIS3-NEXT:and %o3, %o4, %o3 ; VIS3-NEXT:add %o2, %o3, %o2 ; VIS3-NEXT:mulx %o1, %o0, %o1 ; VIS3-NEXT:retl ; VIS3-NEXT:mov %o2, %o0 ``` https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add initial lowering of vector.contract to SVE `*MMLA` instructions (PR #135636)
https://github.com/momchil-velikov updated https://github.com/llvm/llvm-project/pull/135636 >From 8e87a7f3b1438d9542d28c90eb9593ebe8cf6500 Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 8 Apr 2025 14:43:54 + Subject: [PATCH] [MLIR][ArmSVE] Add initial lowering of `vector.contract` to SVE `*MMLA` instructions --- mlir/include/mlir/Conversion/Passes.td| 4 + .../Dialect/ArmSVE/Transforms/Transforms.h| 3 + .../Conversion/VectorToLLVM/CMakeLists.txt| 1 + .../VectorToLLVM/ConvertVectorToLLVMPass.cpp | 7 + .../LowerContractionToSMMLAPattern.cpp| 5 +- .../Dialect/ArmSVE/Transforms/CMakeLists.txt | 1 + .../LowerContractionToSVEI8MMPattern.cpp | 304 ++ .../Vector/CPU/ArmSVE/vector-smmla.mlir | 94 ++ .../Vector/CPU/ArmSVE/vector-summla.mlir | 85 + .../Vector/CPU/ArmSVE/vector-ummla.mlir | 94 ++ .../Vector/CPU/ArmSVE/vector-usmmla.mlir | 95 ++ .../CPU/ArmSVE/contraction-smmla-4x8x4.mlir | 117 +++ .../ArmSVE/contraction-smmla-8x8x8-vs2.mlir | 159 + .../CPU/ArmSVE/contraction-summla-4x8x4.mlir | 118 +++ .../CPU/ArmSVE/contraction-ummla-4x8x4.mlir | 119 +++ .../CPU/ArmSVE/contraction-usmmla-4x8x4.mlir | 117 +++ 16 files changed, 1322 insertions(+), 1 deletion(-) create mode 100644 mlir/lib/Dialect/ArmSVE/Transforms/LowerContractionToSVEI8MMPattern.cpp create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-smmla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-summla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-ummla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-usmmla.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-smmla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-smmla-8x8x8-vs2.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-summla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-ummla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-usmmla-4x8x4.mlir diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index bbba495e613b2..930d8b44abca0 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -1406,6 +1406,10 @@ def ConvertVectorToLLVMPass : Pass<"convert-vector-to-llvm"> { "bool", /*default=*/"false", "Enables the use of ArmSVE dialect while lowering the vector " "dialect.">, +Option<"armI8MM", "enable-arm-i8mm", + "bool", /*default=*/"false", + "Enables the use of Arm FEAT_I8MM instructions while lowering " + "the vector dialect.">, Option<"x86Vector", "enable-x86vector", "bool", /*default=*/"false", "Enables the use of X86Vector dialect while lowering the vector " diff --git a/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h b/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h index 8665c8224cc45..232e2be29e574 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h +++ b/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h @@ -20,6 +20,9 @@ class RewritePatternSet; void populateArmSVELegalizeForLLVMExportPatterns( const LLVMTypeConverter &converter, RewritePatternSet &patterns); +void populateLowerContractionToSVEI8MMPatternPatterns( +RewritePatternSet &patterns); + /// Configure the target to support lowering ArmSVE ops to ops that map to LLVM /// intrinsics. void configureArmSVELegalizeForExportTarget(LLVMConversionTarget &target); diff --git a/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt b/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt index 330474a718e30..8e2620029c354 100644 --- a/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt +++ b/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt @@ -35,6 +35,7 @@ add_mlir_conversion_library(MLIRVectorToLLVMPass MLIRVectorToLLVM MLIRArmNeonDialect + MLIRArmNeonTransforms MLIRArmSVEDialect MLIRArmSVETransforms MLIRAMXDialect diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp index 7082b92c95d1d..1e6c8122b1d0e 100644 --- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp +++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp @@ -14,6 +14,7 @@ #include "mlir/Dialect/AMX/Transforms.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/ArmNeon/ArmNeonDialect.h" +#include "mlir/Dialect/ArmNeon/Transforms.h" #include "mlir/Dialect/ArmSVE/IR/ArmSVEDialect.h" #include "mlir/Dialect/ArmSVE/Transforms/Transforms.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -82,6 +83,12 @@ void ConvertVectorToLLVMPass::runOnOperation() { populateVectorStepLoweringPatterns(pa
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add initial lowering of vector.contract to SVE `*MMLA` instructions (PR #135636)
https://github.com/momchil-velikov updated https://github.com/llvm/llvm-project/pull/135636 >From 8e87a7f3b1438d9542d28c90eb9593ebe8cf6500 Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 8 Apr 2025 14:43:54 + Subject: [PATCH] [MLIR][ArmSVE] Add initial lowering of `vector.contract` to SVE `*MMLA` instructions --- mlir/include/mlir/Conversion/Passes.td| 4 + .../Dialect/ArmSVE/Transforms/Transforms.h| 3 + .../Conversion/VectorToLLVM/CMakeLists.txt| 1 + .../VectorToLLVM/ConvertVectorToLLVMPass.cpp | 7 + .../LowerContractionToSMMLAPattern.cpp| 5 +- .../Dialect/ArmSVE/Transforms/CMakeLists.txt | 1 + .../LowerContractionToSVEI8MMPattern.cpp | 304 ++ .../Vector/CPU/ArmSVE/vector-smmla.mlir | 94 ++ .../Vector/CPU/ArmSVE/vector-summla.mlir | 85 + .../Vector/CPU/ArmSVE/vector-ummla.mlir | 94 ++ .../Vector/CPU/ArmSVE/vector-usmmla.mlir | 95 ++ .../CPU/ArmSVE/contraction-smmla-4x8x4.mlir | 117 +++ .../ArmSVE/contraction-smmla-8x8x8-vs2.mlir | 159 + .../CPU/ArmSVE/contraction-summla-4x8x4.mlir | 118 +++ .../CPU/ArmSVE/contraction-ummla-4x8x4.mlir | 119 +++ .../CPU/ArmSVE/contraction-usmmla-4x8x4.mlir | 117 +++ 16 files changed, 1322 insertions(+), 1 deletion(-) create mode 100644 mlir/lib/Dialect/ArmSVE/Transforms/LowerContractionToSVEI8MMPattern.cpp create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-smmla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-summla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-ummla.mlir create mode 100644 mlir/test/Dialect/Vector/CPU/ArmSVE/vector-usmmla.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-smmla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-smmla-8x8x8-vs2.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-summla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-ummla-4x8x4.mlir create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/contraction-usmmla-4x8x4.mlir diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index bbba495e613b2..930d8b44abca0 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -1406,6 +1406,10 @@ def ConvertVectorToLLVMPass : Pass<"convert-vector-to-llvm"> { "bool", /*default=*/"false", "Enables the use of ArmSVE dialect while lowering the vector " "dialect.">, +Option<"armI8MM", "enable-arm-i8mm", + "bool", /*default=*/"false", + "Enables the use of Arm FEAT_I8MM instructions while lowering " + "the vector dialect.">, Option<"x86Vector", "enable-x86vector", "bool", /*default=*/"false", "Enables the use of X86Vector dialect while lowering the vector " diff --git a/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h b/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h index 8665c8224cc45..232e2be29e574 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h +++ b/mlir/include/mlir/Dialect/ArmSVE/Transforms/Transforms.h @@ -20,6 +20,9 @@ class RewritePatternSet; void populateArmSVELegalizeForLLVMExportPatterns( const LLVMTypeConverter &converter, RewritePatternSet &patterns); +void populateLowerContractionToSVEI8MMPatternPatterns( +RewritePatternSet &patterns); + /// Configure the target to support lowering ArmSVE ops to ops that map to LLVM /// intrinsics. void configureArmSVELegalizeForExportTarget(LLVMConversionTarget &target); diff --git a/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt b/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt index 330474a718e30..8e2620029c354 100644 --- a/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt +++ b/mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt @@ -35,6 +35,7 @@ add_mlir_conversion_library(MLIRVectorToLLVMPass MLIRVectorToLLVM MLIRArmNeonDialect + MLIRArmNeonTransforms MLIRArmSVEDialect MLIRArmSVETransforms MLIRAMXDialect diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp index 7082b92c95d1d..1e6c8122b1d0e 100644 --- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp +++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp @@ -14,6 +14,7 @@ #include "mlir/Dialect/AMX/Transforms.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/ArmNeon/ArmNeonDialect.h" +#include "mlir/Dialect/ArmNeon/Transforms.h" #include "mlir/Dialect/ArmSVE/IR/ArmSVEDialect.h" #include "mlir/Dialect/ArmSVE/Transforms/Transforms.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -82,6 +83,12 @@ void ConvertVectorToLLVMPass::runOnOperation() { populateVectorStepLoweringPatterns(pa
[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: detect authentication oracles (PR #135663)
llvmbot wrote: @llvm/pr-subscribers-bolt Author: Anatoly Trosinenko (atrosinenko) Changes Implement the detection of authentication instructions whose results can be inspected by an attacker to know whether authentication succeeded. As the properties of output registers of authentication instructions are inspected, add a second set of analysis-related classes to iterate over the instructions in reverse order. --- Patch is 50.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135663.diff 5 Files Affected: - (modified) bolt/include/bolt/Core/MCPlusBuilder.h (+3) - (modified) bolt/include/bolt/Passes/PAuthGadgetScanner.h (+12) - (modified) bolt/lib/Passes/PAuthGadgetScanner.cpp (+537) - (added) bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s (+675) - (modified) bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s (+78) ``diff diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index 9d50036b8083b..4f895fb5f9cc5 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -622,6 +622,9 @@ class MCPlusBuilder { /// controlled, provided InReg and executable code are not. Please note that /// registers other than InReg as well as the contents of memory which is /// writable by the process should be considered attacker-controlled. + /// + /// The instruction should not write any values derived from InReg anywhere, + /// except for OutReg. virtual std::optional> analyzeAddressArithmeticsForPtrAuth(const MCInst &Inst) const { llvm_unreachable("not implemented"); diff --git a/bolt/include/bolt/Passes/PAuthGadgetScanner.h b/bolt/include/bolt/Passes/PAuthGadgetScanner.h index 3b6c1f6af94a0..2b923e362941f 100644 --- a/bolt/include/bolt/Passes/PAuthGadgetScanner.h +++ b/bolt/include/bolt/Passes/PAuthGadgetScanner.h @@ -261,6 +261,15 @@ class ClobberingInfo : public ExtraInfo { void print(raw_ostream &OS, const MCInstReference Location) const override; }; +class LeakageInfo : public ExtraInfo { + SmallVector LeakingInstrs; + +public: + LeakageInfo(const ArrayRef Instrs) : LeakingInstrs(Instrs) {} + + void print(raw_ostream &OS, const MCInstReference Location) const override; +}; + /// A brief version of a report that can be further augmented with the details. /// /// It is common for a particular type of gadget detector to be tied to some @@ -302,6 +311,9 @@ class FunctionAnalysis { void findUnsafeUses(SmallVector> &Reports); void augmentUnsafeUseReports(const ArrayRef> Reports); + void findUnsafeDefs(SmallVector> &Reports); + void augmentUnsafeDefReports(const ArrayRef> Reports); + public: FunctionAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId, bool PacRetGadgetsOnly) diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp b/bolt/lib/Passes/PAuthGadgetScanner.cpp index b3081f034e8ee..f403caddf3fd8 100644 --- a/bolt/lib/Passes/PAuthGadgetScanner.cpp +++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp @@ -712,6 +712,460 @@ SrcSafetyAnalysis::create(BinaryFunction &BF, RegsToTrackInstsFor); } +/// A state representing which registers are safe to be used as the destination +/// operand of an authentication instruction. +/// +/// Similar to SrcState, it is the analysis that should take register aliasing +/// into account. +/// +/// Depending on the implementation, it may be possible that an authentication +/// instruction returns an invalid pointer on failure instead of terminating +/// the program immediately (assuming the program will crash as soon as that +/// pointer is dereferenced). To prevent brute-forcing the correct signature, +/// it should be impossible for an attacker to test if a pointer is correctly +/// signed - either the program should be terminated on authentication failure +/// or it should be impossible to tell whether authentication succeeded or not. +/// +/// For that reason, a restricted set of operations is allowed on any register +/// containing a value derived from the result of an authentication instruction +/// until that register is either wiped or checked not to contain a result of a +/// failed authentication. +/// +/// Specifically, the safety property for a register is computed by iterating +/// the instructions in backward order: the source register Xn of an instruction +/// Inst is safe if at least one of the following is true: +/// * Inst checks if Xn contains the result of a successful authentication and +/// terminates the program on failure. Note that Inst can either naturally +/// dereference Xn (load, branch, return, etc. instructions) or be the first +/// instruction of an explicit checking sequence. +/// * Inst performs safe address arithmetic AND both source and result +/// registers, as well as any temporary registers, must be safe after +/// execution
[llvm-branch-commits] [clang] release/20.x: [Clang] Fix a lambda pattern comparison mismatch after ecc7e6ce4 (#133863) (PR #134194)
erichkeane wrote: Yes, I think this would be ok. We haven't seen any regressions on it, so I'm much more comfortable now. https://github.com/llvm/llvm-project/pull/134194 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use umulxhi to do extending 64x64->128 multiply when we have VIS3 (PR #135714)
@@ -294,4 +294,13 @@ def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; // VIS3 instruction patterns. let Predicates = [HasVIS3] in { def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 ยง7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), +(ANDrr (SRAXri $rhs, 63), $lhs)))>; koachan wrote: It seems so. Setting MULHS to Expand results in it producing two additional `mulx`es, in addition to the `umulxhi`. https://github.com/llvm/llvm-project/pull/135714 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [HLSL] Adding support for Root Constants in LLVM Metadata (PR #135085)
@@ -52,6 +59,45 @@ static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, return false; } +static bool extractMdValue(uint32_t &Value, MDNode *Node, unsigned int OpId) { + + auto *CI = mdconst::extract(Node->getOperand(OpId)); + if (CI == nullptr) +return true; + + Value = CI->getZExtValue(); + return false; +} + +static bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *RootFlagNode) { + + if (RootFlagNode->getNumOperands() != 5) +return reportError(Ctx, "Invalid format for RootConstants Element"); + + mcdxbc::RootParameter NewParameter; + NewParameter.Header.ParameterType = dxbc::RootParameterType::Constants32Bit; + + uint32_t SV; + if (extractMdValue(SV, RootFlagNode, 1)) +return reportError(Ctx, "Invalid value for ShaderVisibility"); + + NewParameter.Header.ShaderVisibility = (dxbc::ShaderVisibility)SV; + + if (extractMdValue(NewParameter.Constants.ShaderRegister, RootFlagNode, 2)) +return reportError(Ctx, "Invalid value for ShaderRegister"); + + if (extractMdValue(NewParameter.Constants.RegisterSpace, RootFlagNode, 3)) +return reportError(Ctx, "Invalid value for RegisterSpace"); + + if (extractMdValue(NewParameter.Constants.Num32BitValues, RootFlagNode, 4)) +return reportError(Ctx, "Invalid value for Num32BitValues"); inbelic wrote: Only the "Invalid value for ShaderVisibility" has a test demonstrating its functionality. Maybe it is too verbose to include a test case for each diag type, or, they are all reporting the same error (expected an i32) and we could move that logic into `extractMdValue`? https://github.com/llvm/llvm-project/pull/135085 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [HLSL] Adding support for Root Constants in LLVM Metadata (PR #135085)
https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/135085 >From 9b59d0108f6b23c039e2c417247216862073cd4b Mon Sep 17 00:00:00 2001 From: joaosaffran Date: Wed, 9 Apr 2025 21:05:58 + Subject: [PATCH 1/5] adding support for root constants in metadata generation --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 120 +- llvm/lib/Target/DirectX/DXILRootSignature.h | 6 +- .../RootSignature-Flags-Validation-Error.ll | 7 +- .../RootSignature-RootConstants.ll| 34 + ...ature-ShaderVisibility-Validation-Error.ll | 20 +++ 5 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootConstants.ll create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-ShaderVisibility-Validation-Error.ll diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 412ab7765a7ae..7686918b0fc75 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -40,6 +40,13 @@ static bool reportError(LLVMContext *Ctx, Twine Message, return true; } +static bool reportValueError(LLVMContext *Ctx, Twine ParamName, uint32_t Value, + DiagnosticSeverity Severity = DS_Error) { + Ctx->diagnose(DiagnosticInfoGeneric( + "Invalid value for " + ParamName + ": " + Twine(Value), Severity)); + return true; +} + static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, MDNode *RootFlagNode) { @@ -52,6 +59,45 @@ static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, return false; } +static bool extractMdValue(uint32_t &Value, MDNode *Node, unsigned int OpId) { + + auto *CI = mdconst::extract(Node->getOperand(OpId)); + if (CI == nullptr) +return true; + + Value = CI->getZExtValue(); + return false; +} + +static bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *RootFlagNode) { + + if (RootFlagNode->getNumOperands() != 5) +return reportError(Ctx, "Invalid format for RootConstants Element"); + + mcdxbc::RootParameter NewParameter; + NewParameter.Header.ParameterType = dxbc::RootParameterType::Constants32Bit; + + uint32_t SV; + if (extractMdValue(SV, RootFlagNode, 1)) +return reportError(Ctx, "Invalid value for ShaderVisibility"); + + NewParameter.Header.ShaderVisibility = (dxbc::ShaderVisibility)SV; + + if (extractMdValue(NewParameter.Constants.ShaderRegister, RootFlagNode, 2)) +return reportError(Ctx, "Invalid value for ShaderRegister"); + + if (extractMdValue(NewParameter.Constants.RegisterSpace, RootFlagNode, 3)) +return reportError(Ctx, "Invalid value for RegisterSpace"); + + if (extractMdValue(NewParameter.Constants.Num32BitValues, RootFlagNode, 4)) +return reportError(Ctx, "Invalid value for Num32BitValues"); + + RSD.Parameters.push_back(NewParameter); + + return false; +} + static bool parseRootSignatureElement(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, MDNode *Element) { @@ -62,12 +108,16 @@ static bool parseRootSignatureElement(LLVMContext *Ctx, RootSignatureElementKind ElementKind = StringSwitch(ElementText->getString()) .Case("RootFlags", RootSignatureElementKind::RootFlags) + .Case("RootConstants", RootSignatureElementKind::RootConstants) .Default(RootSignatureElementKind::Error); switch (ElementKind) { case RootSignatureElementKind::RootFlags: return parseRootFlags(Ctx, RSD, Element); + case RootSignatureElementKind::RootConstants: +return parseRootConstants(Ctx, RSD, Element); +break; case RootSignatureElementKind::Error: return reportError(Ctx, "Invalid Root Signature Element: " + ElementText->getString()); @@ -94,10 +144,56 @@ static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, static bool verifyRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; } +static bool verifyShaderVisibility(dxbc::ShaderVisibility Flags) { + switch (Flags) { + + case dxbc::ShaderVisibility::All: + case dxbc::ShaderVisibility::Vertex: + case dxbc::ShaderVisibility::Hull: + case dxbc::ShaderVisibility::Domain: + case dxbc::ShaderVisibility::Geometry: + case dxbc::ShaderVisibility::Pixel: + case dxbc::ShaderVisibility::Amplification: + case dxbc::ShaderVisibility::Mesh: +return true; + } + + return false; +} + +static bool verifyParameterType(dxbc::RootParameterType Flags) { + switch (Flags) { + case dxbc::RootParameterType::Constants32Bit: +return true; + } + + return false; +} + +static bool verifyVersion(uint32_t Version) { + return (Version == 1 || Version == 2); +} + static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -599,8 +600,18 @@ class MCContext { unsigned Flags, unsigned EntrySize); - MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind, -MCSection *Parent, uint32_t Subsection = 0); +private: MaskRay wrote: instead of adding a `private`, just move the `getGOFFSection` to the existing private part. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,112 @@ +; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \ MaskRay wrote: `llc < %s` does not need `-o -`. .ll tests in llvm/test/MC is probably not a good convention we'd recommend. Move to llvm/test/CodeGen/SystemZ, perhaps under a directory zos/ ? https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)
@@ -303,4 +303,10 @@ def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), (SUBrr (UMULXHI $lhs, $rhs), (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), (ANDrr (SRAXri $rhs, 63), $lhs)))>; + +def : Pat<(i64 (ctlz i64:$src)), (LZCNT $src)>; +// 32-bit LZCNT. +// The zero extension will leave us with 32 extra leading zeros, +// so we need to compensate for it. +def : Pat<(i32 (ctlz i32:$src)), (ADDri (LZCNT (SRLri $src, 0)), (i32 -32))>; koachan wrote: `Promote`-ing 32-bit ctlz seems to result in it not using `lzcnt` at all? Or am I doing something wrong here? https://github.com/llvm/llvm-project/pull/135715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/135715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/135715 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][ArmSVE] Add initial lowering of vector.contract to SVE `*MMLA` instructions (PR #135636)
momchil-velikov wrote: > One high-level question - would sharing some code between NEON and SVE be > possible? No, I can't see it happening and resulting in less, or simpler, or easier to maintain code. However, it might be possible to add Neon lowering to this patch and see if the result is any good. https://github.com/llvm/llvm-project/pull/135636 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Add `noundef` to several testcases (NFC) (PR #135799)
llvmbot wrote: @llvm/pr-subscribers-llvm-transforms Author: Iris (el-ev) Changes [ConstraintElim] Add `noundef` to several testcases (NFC) update check --- Full diff: https://github.com/llvm/llvm-project/pull/135799.diff 2 Files Affected: - (modified) llvm/test/Transforms/ConstraintElimination/abs.ll (+93-26) - (modified) llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll (+13-14) ``diff diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index a49b4643ab92c..f1291e41f13b2 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -1,12 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s -define i1 @abs_int_min_is_not_poison(i32 %arg) { +define i1 @abs_int_min_is_not_poison(i32 noundef %arg) { ; CHECK-LABEL: define i1 @abs_int_min_is_not_poison( -; CHECK-SAME: i32 [[ARG:%.*]]) { +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) -; CHECK-NEXT:[[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]] -; CHECK-NEXT:ret i1 [[CMP]] +; CHECK-NEXT:ret i1 true ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) %cmp = icmp sge i32 %abs, %arg @@ -25,8 +24,21 @@ define i1 @abs_int_min_is_poison(i32 %arg) { ret i1 %cmp } -define i1 @abs_plus_one(i32 %arg) { -; CHECK-LABEL: define i1 @abs_plus_one( +define i1 @abs_plus_one_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @abs_plus_one_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1 +; CHECK-NEXT:ret i1 true +; + %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) + %abs_plus_one = add nsw i32 %abs, 1 + %cmp = icmp sge i32 %abs_plus_one, %arg + ret i1 %cmp +} + +define i1 @abs_plus_one_min_is_poison(i32 %arg) { +; CHECK-LABEL: define i1 @abs_plus_one_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT:[[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1 @@ -39,8 +51,22 @@ define i1 @abs_plus_one(i32 %arg) { ret i1 %cmp } -define i1 @arg_minus_one_strict_less(i32 %arg) { -; CHECK-LABEL: define i1 @arg_minus_one_strict_less( +define i1 @arg_minus_one_strict_less_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 +; CHECK-NEXT:ret i1 true +; + %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) + %arg_minus_one = add nsw i32 %arg, -1 + %cmp = icmp slt i32 %arg_minus_one, %abs + ret i1 %cmp +} + + +define i1 @arg_minus_one_strict_less_min_is_poison(i32 %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 @@ -53,8 +79,21 @@ define i1 @arg_minus_one_strict_less(i32 %arg) { ret i1 %cmp } -define i1 @arg_minus_one_strict_greater(i32 %arg) { -; CHECK-LABEL: define i1 @arg_minus_one_strict_greater( +define i1 @arg_minus_one_strict_greater_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 +; CHECK-NEXT:ret i1 false +; + %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) + %arg_minus_one = add nsw i32 %arg, -1 + %cmp = icmp sgt i32 %arg_minus_one, %abs + ret i1 %cmp +} + +define i1 @arg_minus_one_strict_greater_min_is_poison(i32 %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 @@ -67,8 +106,24 @@ define i1 @arg_minus_one_strict_greater(i32 %arg) { ret i1 %cmp } -define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg(i32 %arg) { -; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg( +define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[CMP_
[llvm-branch-commits] [llvm] [ConstraintElim] Add `noundef` to several testcases (NFC) (PR #135799)
https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/135799 [ConstraintElim] Add `noundef` to several testcases (NFC) update check >From ee5f9f45bf07f339e4665fd0f0d3f340902fb374 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 23:54:48 +0800 Subject: [PATCH 1/2] [ConstraintElim] Add `noundef` to several testcases (NFC) --- .../Transforms/ConstraintElimination/abs.ll | 149 +- .../ConstraintElimination/uadd-usub-sat.ll| 32 ++-- 2 files changed, 125 insertions(+), 56 deletions(-) diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index a49b4643ab92c..bd221acec8c9f 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -1,12 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s -define i1 @abs_int_min_is_not_poison(i32 %arg) { +define i1 @abs_int_min_is_not_poison(i32 noundef %arg) { ; CHECK-LABEL: define i1 @abs_int_min_is_not_poison( -; CHECK-SAME: i32 [[ARG:%.*]]) { +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) -; CHECK-NEXT:[[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]] -; CHECK-NEXT:ret i1 [[CMP]] +; CHECK-NEXT:ret i1 true ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) %cmp = icmp sge i32 %abs, %arg @@ -17,21 +16,32 @@ define i1 @abs_int_min_is_poison(i32 %arg) { ; CHECK-LABEL: define i1 @abs_int_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) -; CHECK-NEXT:[[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]] -; CHECK-NEXT:ret i1 [[CMP]] +; CHECK-NEXT:ret i1 true ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %cmp = icmp sge i32 %abs, %arg ret i1 %cmp } -define i1 @abs_plus_one(i32 %arg) { -; CHECK-LABEL: define i1 @abs_plus_one( +define i1 @abs_plus_one_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @abs_plus_one_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1 +; CHECK-NEXT:ret i1 true +; + %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) + %abs_plus_one = add nsw i32 %abs, 1 + %cmp = icmp sge i32 %abs_plus_one, %arg + ret i1 %cmp +} + +define i1 @abs_plus_one_min_is_poison(i32 %arg) { +; CHECK-LABEL: define i1 @abs_plus_one_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT:[[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1 -; CHECK-NEXT:[[CMP:%.*]] = icmp sge i32 [[ABS_PLUS_ONE]], [[ARG]] -; CHECK-NEXT:ret i1 [[CMP]] +; CHECK-NEXT:ret i1 true ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %abs_plus_one = add nsw i32 %abs, 1 @@ -39,13 +49,26 @@ define i1 @abs_plus_one(i32 %arg) { ret i1 %cmp } -define i1 @arg_minus_one_strict_less(i32 %arg) { -; CHECK-LABEL: define i1 @arg_minus_one_strict_less( +define i1 @arg_minus_one_strict_less_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 +; CHECK-NEXT:ret i1 true +; + %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) + %arg_minus_one = add nsw i32 %arg, -1 + %cmp = icmp slt i32 %arg_minus_one, %abs + ret i1 %cmp +} + + +define i1 @arg_minus_one_strict_less_min_is_poison(i32 %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 -; CHECK-NEXT:[[CMP:%.*]] = icmp slt i32 [[ARG_MINUS_ONE]], [[ABS]] -; CHECK-NEXT:ret i1 [[CMP]] +; CHECK-NEXT:ret i1 true ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %arg_minus_one = add nsw i32 %arg, -1 @@ -53,13 +76,25 @@ define i1 @arg_minus_one_strict_less(i32 %arg) { ret i1 %cmp } -define i1 @arg_minus_one_strict_greater(i32 %arg) { -; CHECK-LABEL: define i1 @arg_minus_one_strict_greater( +define i1 @arg_minus_one_strict_greater_min_is_not_poison(i32 noundef %arg) { +; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_not_poison( +; CHECK-SAME: i32 noundef [[ARG:%.*]]) { +; CHECK-NEXT:[[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) +; CHECK-NEXT:[[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 +; CHECK-NEXT:ret i1 false +; + %abs = tail cal
[llvm-branch-commits] [llvm] [ConstraintElim] Add `noundef` to several testcases (NFC) (PR #135799)
el-ev wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/135799?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#135799** https://app.graphite.dev/github/pr/llvm/llvm-project/135799?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> ๐ https://app.graphite.dev/github/pr/llvm/llvm-project/135799?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#135754** https://app.graphite.dev/github/pr/llvm/llvm-project/135754?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#135744** https://app.graphite.dev/github/pr/llvm/llvm-project/135744?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/135799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Add `noundef` to several testcases (NFC) (PR #135799)
https://github.com/el-ev ready_for_review https://github.com/llvm/llvm-project/pull/135799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135785 >From 9c908f93ba64524323ecc0a95cd6e7b3e061c2a0 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 20:20:45 +0800 Subject: [PATCH] [ConstraintElim] Simplify `usub_with_overflow` when A uge B --- .../Scalar/ConstraintElimination.cpp | 10 ++ .../usub-with-overflow.ll | 33 +++ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6d17b36b7d9ea..e030f0fac4c0d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1123,6 +1123,7 @@ void State::addInfoFor(BasicBlock &BB) { // Enqueue overflow intrinsics for simplification. case Intrinsic::sadd_with_overflow: case Intrinsic::ssub_with_overflow: +case Intrinsic::usub_with_overflow: case Intrinsic::ucmp: case Intrinsic::scmp: WorkList.push_back( @@ -1785,6 +1786,15 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, Changed = replaceSubOverflowUses(II, A, B, ToRemove); break; } + case Intrinsic::usub_with_overflow: { +// usub overflows iff A < B +// TODO: If the operation is guaranteed to overflow, we could +// also apply some simplifications. +if (DoesConditionHold(CmpInst::ICMP_UGE, A, B, Info)) { + Changed = replaceSubOverflowUses(II, A, B, ToRemove); +} +break; + } } return Changed; diff --git a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll index 06bfd8269d97d..0a3c4eb00fd25 100644 --- a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll +++ b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll @@ -9,11 +9,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -41,11 +39,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -75,12 +71,11 @@ define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] ; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) ; CHECK-NEXT:call void @use_res({ i8, i1 } [[OP]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -111,11 +106,9 @@ define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { ; CHECK-NEXT:[[OR:%.*]] = or i1 [[C_2]], [[C_1]] ; CHECK-NEXT:br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FA
[llvm-branch-commits] [clang] Silence -Wcast-function-type warnings on idiomatic Windows code (#135โฆ (PR #135798)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) Changes โฆ660) On Windows, GetProcAddress() is the API used to dynamically load function pointers (similar to dlsym on Linux). This API returns a function pointer (a typedef named FARPROC), which means that casting from the call to the eventual correct type is technically a function type mismatch on the cast. However, because this is idiomatic code on Windows, we should accept it unless -Wcast-function-type-strict is passed. This was brought up in post-commit review feedback on https://github.com/llvm/llvm-project/pull/86131 --- Full diff: https://github.com/llvm/llvm-project/pull/135798.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+10) - (modified) clang/lib/Sema/SemaCast.cpp (+23) - (added) clang/test/Sema/warn-cast-function-type-win.c (+36) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f4befc242f28b..b8f26ec9a5447 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -694,6 +694,16 @@ Improvements to Clang's diagnostics match a template template parameter, in terms of the C++17 relaxed matching rules instead of the old ones. +- No longer diagnosing idiomatic function pointer casts on Windows under + ``-Wcast-function-type-mismatch`` (which is enabled by ``-Wextra``). Clang + would previously warn on this construct, but will no longer do so on Windows: + + .. code-block:: c + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +HMODULE Lib = LoadLibrary("kernel32"); +PGNSI FnPtr = (PGNSI)GetProcAddress(Lib, "GetNativeSystemInfo"); + - Don't emit duplicated dangling diagnostics. (#GH93386). - Improved diagnostic when trying to befriend a concept. (#GH45182). diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 54bc52fa2ac40..d0d44e8899133 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1151,10 +1151,33 @@ static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, return false; }; + auto IsFarProc = [](const FunctionType *T) { +// The definition of FARPROC depends on the platform in terms of its return +// type, which could be int, or long long, etc. We'll look for a source +// signature for: (*)() and call that "close enough" to +// FARPROC to be sufficient to silence the diagnostic. This is similar to +// how we allow casts between function pointers and void * for supporting +// dlsym. +// Note: we could check for __stdcall on the function pointer as well, but +// that seems like splitting hairs. +if (!T->getReturnType()->isIntegerType()) + return false; +if (const auto *PT = T->getAs()) + return !PT->isVariadic() && PT->getNumParams() == 0; +return true; + }; + // Skip if either function type is void(*)(void) if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy)) return 0; + // On Windows, GetProcAddress() returns a FARPROC, which is a typedef for a + // function pointer type (with no prototype, in C). We don't want to diagnose + // this case so we don't diagnose idiomatic code on Windows. + if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() && + IsFarProc(SrcFTy)) +return 0; + // Check return type. if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(), Self.Context)) diff --git a/clang/test/Sema/warn-cast-function-type-win.c b/clang/test/Sema/warn-cast-function-type-win.c new file mode 100644 index 0..4e7ba33b258d8 --- /dev/null +++ b/clang/test/Sema/warn-cast-function-type-win.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=windows +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=linux +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=linux,linux-cpp +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wcast-function-type-strict -x c++ -verify=strict +// windows-no-diagnostics + +// On Windows targets, this is expected to compile fine, and on non-Windows +// targets, this should diagnose the mismatch. This is to allow for idiomatic +// use of GetProcAddress, similar to what we do for dlsym. On non-Windows +// targets, this should be diagnosed. +typedef int (*FARPROC1)(); +typedef unsigned long long (*FARPROC2)(); + +FARPROC1 GetProcAddress1(void); +FARPROC2 GetProcAddress2(void); + +typedef int (*test1_type)(int); +typedef float(*test2_type)(); + +void test(void) { + // This does not diagnose on Linux in C mode because FARPROC1 has a match
[llvm-branch-commits] [clang] Silence -Wcast-function-type warnings on idiomatic Windows code (#135โฆ (PR #135798)
https://github.com/erichkeane approved this pull request. LGTM here too. https://github.com/llvm/llvm-project/pull/135798 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ConstraintElim] Simplify `usub_with_overflow` when A uge B (PR #135785)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135785 >From 9c908f93ba64524323ecc0a95cd6e7b3e061c2a0 Mon Sep 17 00:00:00 2001 From: Iris Shi <0...@owo.li> Date: Tue, 15 Apr 2025 20:20:45 +0800 Subject: [PATCH] [ConstraintElim] Simplify `usub_with_overflow` when A uge B --- .../Scalar/ConstraintElimination.cpp | 10 ++ .../usub-with-overflow.ll | 33 +++ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 6d17b36b7d9ea..e030f0fac4c0d 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1123,6 +1123,7 @@ void State::addInfoFor(BasicBlock &BB) { // Enqueue overflow intrinsics for simplification. case Intrinsic::sadd_with_overflow: case Intrinsic::ssub_with_overflow: +case Intrinsic::usub_with_overflow: case Intrinsic::ucmp: case Intrinsic::scmp: WorkList.push_back( @@ -1785,6 +1786,15 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, Changed = replaceSubOverflowUses(II, A, B, ToRemove); break; } + case Intrinsic::usub_with_overflow: { +// usub overflows iff A < B +// TODO: If the operation is guaranteed to overflow, we could +// also apply some simplifications. +if (DoesConditionHold(CmpInst::ICMP_UGE, A, B, Info)) { + Changed = replaceSubOverflowUses(II, A, B, ToRemove); +} +break; + } } return Changed; diff --git a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll index 06bfd8269d97d..0a3c4eb00fd25 100644 --- a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll +++ b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll @@ -9,11 +9,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -41,11 +39,9 @@ define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -75,12 +71,11 @@ define i8 @sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) { ; CHECK-NEXT:[[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]] ; CHECK-NEXT:br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] ; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) ; CHECK-NEXT:call void @use_res({ i8, i1 } [[OP]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:br i1 false, label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] ; CHECK: exit.ok: -; CHECK-NEXT:[[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0 ; CHECK-NEXT:ret i8 [[RES]] ; CHECK: exit.fail: ; CHECK-NEXT:ret i8 0 @@ -111,11 +106,9 @@ define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) { ; CHECK-NEXT:[[OR:%.*]] = or i1 [[C_2]], [[C_1]] ; CHECK-NEXT:br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]] ; CHECK: math: -; CHECK-NEXT:[[OP:%.*]] = tail call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]]) -; CHECK-NEXT:[[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1 -; CHECK-NEXT:br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]] +; CHECK-NEXT:[[RES:%.*]] = sub i8 [[B]], [[A]] +; CHECK-NEXT:br i1 false, label [[EXIT_FA
[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
@@ -0,0 +1,145 @@ +//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/MC/MCSectionGOFF.h" +#include "llvm/BinaryFormat/GOFF.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) { + if (Rmode != GOFF::ESD_RMODE_None) { +OS << "RMODE" << (UseParenthesis ? '(' : ' '); +switch (Rmode) { +case GOFF::ESD_RMODE_24: + OS << "24"; + break; +case GOFF::ESD_RMODE_31: + OS << "31"; + break; +case GOFF::ESD_RMODE_64: + OS << "64"; + break; +case GOFF::ESD_RMODE_None: + break; +} +if (UseParenthesis) + OS << ')'; + } +} + +void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName, + bool EmitAmodeAndRmode, GOFF::ESDAmode Amode, + GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment, + GOFF::ESDLoadingBehavior LoadBehavior, + GOFF::ESDExecutable Executable, bool IsReadOnly, + StringRef PartName) { + if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) { +OS << ParentName << " AMODE "; +switch (Amode) { +case GOFF::ESD_AMODE_24: + OS << "24"; + break; +case GOFF::ESD_AMODE_31: + OS << "31"; + break; +case GOFF::ESD_AMODE_ANY: + OS << "ANY"; + break; +case GOFF::ESD_AMODE_64: + OS << "64"; + break; +case GOFF::ESD_AMODE_MIN: + OS << "ANY64"; + break; +case GOFF::ESD_AMODE_None: + break; +} +OS << "\n"; + } + if (EmitAmodeAndRmode && Rmode != GOFF::ESD_RMODE_None) { +OS << ParentName << ' '; +emitRMode(OS, Rmode, /*UseParenthesis=*/false); +OS << "\n"; + } + OS << Name << " CATTR "; + OS << "ALIGN(" << static_cast(Alignment) << ")"; + switch (LoadBehavior) { + case GOFF::ESD_LB_Deferred: +OS << ",DEFLOAD"; +break; + case GOFF::ESD_LB_NoLoad: +OS << ",NOLOAD"; +break; + default: +break; + } + switch (Executable) { + case GOFF::ESD_EXE_CODE: +OS << ",EXECUTABLE"; +break; + case GOFF::ESD_EXE_DATA: +OS << ",NOTEXECUTABLE"; +break; + default: +break; + } + if (IsReadOnly) +OS << ",READONLY"; + if (Rmode != GOFF::ESD_RMODE_None) { +OS << ','; +emitRMode(OS, Rmode, /*UseParenthesis=*/true); + } + if (!PartName.empty()) +OS << ",PART(" << PartName << ")"; + OS << '\n'; +} +} // namespace + +void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, + raw_ostream &OS, + uint32_t Subsection) const { + switch (SymbolType) { + case GOFF::ESD_ST_SectionDefinition: { +OS << Name << " CSECT\n"; +Emitted = true; +break; + } + case GOFF::ESD_ST_ElementDefinition: { +bool ParentEmitted = getParent()->Emitted; +getParent()->printSwitchToSection(MAI, T, OS, Subsection); +if (!Emitted) { + emitCATTR(OS, Name, getParent()->getName(), !ParentEmitted, +EDAttributes.Amode, EDAttributes.Rmode, EDAttributes.Alignment, +EDAttributes.LoadBehavior, EDAttributes.Executable, +EDAttributes.IsReadOnly, StringRef()); + Emitted = true; +} else + OS << Name << " CATTR ,\n"; +break; + } + case GOFF::ESD_ST_PartReference: { +MCSectionGOFF *ED = getParent(); +bool SDEmitted = ED->getParent()->Emitted; +ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection); +if (!Emitted) { + emitCATTR(OS, ED->getName(), ED->getParent()->getName(), !SDEmitted, +PRAttributes.Amode, getParent()->EDAttributes.Rmode, +PRAttributes.Alignment, getParent()->EDAttributes.LoadBehavior, +PRAttributes.Executable, PRAttributes.IsReadOnly, Name); redstar wrote: Yes, PRIORITY is needed. I also emit the XATTR now. I emit REFERENCE(CODE/DATA), but I test if it is needed. It does not interact with CATTR [NON]EXECUTABLE but may interact with the EXECUTABLE/DATA property set at the external symbol referring to this part. In the past I got binder errors when when those were not matching but I have to check if this is true for PR symbols. https://github.com/llvm/llvm-project/pull/133799 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits