Skip to content

Commit 525ccd4

Browse files
authored
Merge branch 'main' into amdgpu-loopalign
2 parents 676038c + 77cb098 commit 525ccd4

File tree

5 files changed

+322
-29
lines changed

5 files changed

+322
-29
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
//===-- include/flang/Evaluate/rewrite.h ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef FORTRAN_EVALUATE_REWRITE_H_
9+
#define FORTRAN_EVALUATE_REWRITE_H_
10+
11+
#include "flang/Common/visit.h"
12+
#include "flang/Evaluate/expression.h"
13+
#include "flang/Support/Fortran.h"
14+
#include "llvm/ADT/STLExtras.h"
15+
16+
#include <tuple>
17+
#include <type_traits>
18+
#include <utility>
19+
#include <variant>
20+
21+
namespace Fortran::evaluate {
22+
namespace rewrite {
23+
namespace detail {
24+
template <typename, typename = void> //
25+
struct IsOperation {
26+
static constexpr bool value{false};
27+
};
28+
29+
template <typename T>
30+
struct IsOperation<T, std::void_t<decltype(T::operands)>> {
31+
static constexpr bool value{true};
32+
};
33+
} // namespace detail
34+
35+
template <typename T>
36+
constexpr bool is_operation_v{detail::IsOperation<T>::value};
37+
38+
/// Individual Expr<T> rewriter that simply constructs an expression that is
39+
/// identical to the input. This is a suitable base class for all user-defined
40+
/// rewriters.
41+
struct Identity {
42+
template <typename T, typename U>
43+
Expr<T> operator()(Expr<T> &&x, const U &op) {
44+
return std::move(x);
45+
}
46+
};
47+
48+
/// Bottom-up Expr<T> rewriter.
49+
///
50+
/// The Mutator traverses and reconstructs given Expr<T>. Going bottom-up,
51+
/// whenever the traversal visits a sub-node of type Expr<U> (for some U),
52+
/// it will invoke the user-provided rewriter via the () operator.
53+
///
54+
/// If x is of type Expr<U>, it will call (in pseudo-code):
55+
/// rewriter_(x, active_member_of(x.u))
56+
/// The second parameter is there to make it easier to overload the () operator
57+
/// for specific operations in Expr<...>.
58+
///
59+
/// The user rewriter is only invoked for Expr<U>, not for Operation, nor any
60+
/// other subobject.
61+
template <typename Rewriter> struct Mutator {
62+
Mutator(Rewriter &rewriter) : rewriter_(rewriter) {}
63+
64+
template <typename T, typename U = llvm::remove_cvref_t<T>>
65+
U operator()(T &&x) {
66+
if constexpr (std::is_lvalue_reference_v<T>) {
67+
return Mutate(U(x));
68+
} else {
69+
return Mutate(std::move(x));
70+
}
71+
}
72+
73+
private:
74+
template <typename T> struct LambdaWithRvalueCapture {
75+
LambdaWithRvalueCapture(Rewriter &r, Expr<T> &&c)
76+
: rewriter_(r), capture_(std::move(c)) {}
77+
template <typename S> Expr<T> operator()(const S &s) {
78+
return rewriter_(std::move(capture_), s);
79+
}
80+
81+
private:
82+
Rewriter &rewriter_;
83+
Expr<T> &&capture_;
84+
};
85+
86+
template <typename T, typename = std::enable_if_t<!is_operation_v<T>>>
87+
T Mutate(T &&x) const {
88+
return std::move(x);
89+
}
90+
91+
template <typename D, typename = std::enable_if_t<is_operation_v<D>>>
92+
D Mutate(D &&op, std::make_index_sequence<D::operands> t = {}) const {
93+
return MutateOp(std::move(op), t);
94+
}
95+
96+
template <typename T> //
97+
Expr<T> Mutate(Expr<T> &&x) const {
98+
// First construct the new expression with the rewritten op.
99+
Expr<T> n{common::visit(
100+
[&](auto &&s) { //
101+
return Expr<T>(Mutate(std::move(s)));
102+
},
103+
std::move(x.u))};
104+
// Return the rewritten expression. The second visit is to make sure
105+
// that the second argument in the call to the rewriter is a part of
106+
// the Expr<T> passed to it.
107+
return common::visit(
108+
LambdaWithRvalueCapture<T>(rewriter_, std::move(n)), std::move(n.u));
109+
}
110+
111+
template <typename... Ts>
112+
std::variant<Ts...> Mutate(std::variant<Ts...> &&u) const {
113+
return common::visit(
114+
[this](auto &&s) { return Mutate(std::move(s)); }, std::move(u));
115+
}
116+
117+
template <typename... Ts>
118+
std::tuple<Ts...> Mutate(std::tuple<Ts...> &&t) const {
119+
return MutateTuple(std::move(t), std::index_sequence_for<Ts...>{});
120+
}
121+
122+
template <typename... Ts, size_t... Is>
123+
std::tuple<Ts...> MutateTuple(
124+
std::tuple<Ts...> &&t, std::index_sequence<Is...>) const {
125+
return std::make_tuple(Mutate(std::move(std::get<Is>(t))...));
126+
}
127+
128+
template <typename D, size_t... Is>
129+
D MutateOp(D &&op, std::index_sequence<Is...>) const {
130+
return D(Mutate(std::move(op.template operand<Is>()))...);
131+
}
132+
133+
template <typename T, size_t... Is>
134+
Extremum<T> MutateOp(Extremum<T> &&op, std::index_sequence<Is...>) const {
135+
return Extremum<T>(
136+
op.ordering, Mutate(std::move(op.template operand<Is>()))...);
137+
}
138+
139+
template <int K, size_t... Is>
140+
ComplexComponent<K> MutateOp(
141+
ComplexComponent<K> &&op, std::index_sequence<Is...>) const {
142+
return ComplexComponent<K>(
143+
op.isImaginaryPart, Mutate(std::move(op.template operand<Is>()))...);
144+
}
145+
146+
template <int K, size_t... Is>
147+
LogicalOperation<K> MutateOp(
148+
LogicalOperation<K> &&op, std::index_sequence<Is...>) const {
149+
return LogicalOperation<K>(
150+
op.logicalOperator, Mutate(std::move(op.template operand<Is>()))...);
151+
}
152+
153+
Rewriter &rewriter_;
154+
};
155+
156+
template <typename Rewriter> Mutator(Rewriter &) -> Mutator<Rewriter>;
157+
} // namespace rewrite
158+
} // namespace Fortran::evaluate
159+
160+
#endif // FORTRAN_EVALUATE_REWRITE_H_

libcxx/utils/ci/docker-compose.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
x-versions: &compiler_versions
22
GCC_HEAD_VERSION: 16
3-
LLVM_HEAD_VERSION: 21
3+
LLVM_HEAD_VERSION: 22
4+
5+
x-image-versions: &image_versions
6+
BASE_IMAGE: ubuntu:jammy
7+
ACTIONS_BASE_IMAGE: builder-base
48

59
services:
610
builder-base:
@@ -10,8 +14,7 @@ services:
1014
dockerfile: Dockerfile
1115
target: builder-base
1216
args:
13-
BASE_IMAGE: ubuntu:jammy
14-
<<: *compiler_versions
17+
<<: [*image_versions, *compiler_versions]
1518

1619
actions-builder:
1720
image: ghcr.io/llvm/libcxx-linux-builder:${TAG}
@@ -20,10 +23,8 @@ services:
2023
dockerfile: Dockerfile
2124
target: actions-builder
2225
args:
23-
BASE_IMAGE: ubuntu:jammy
24-
ACTIONS_BASE_IMAGE: builder-base
2526
GITHUB_RUNNER_VERSION: "2.326.0"
26-
<<: *compiler_versions
27+
<<: [*image_versions, *compiler_versions]
2728

2829
android-buildkite-builder:
2930
image: ghcr.io/llvm/libcxx-android-builder:${TAG}

lldb/scripts/framework-header-fix.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,6 @@ static bool isConflictIP(IRBuilder<>::InsertPoint IP1,
9292
return IP1.getBlock() == IP2.getBlock() && IP1.getPoint() == IP2.getPoint();
9393
}
9494

95-
/// This is wrapper over IRBuilderBase::restoreIP that also restores the current
96-
/// debug location to the last instruction in the specified basic block if the
97-
/// insert point points to the end of the block.
98-
static void restoreIPandDebugLoc(llvm::IRBuilderBase &Builder,
99-
llvm::IRBuilderBase::InsertPoint IP) {
100-
Builder.restoreIP(IP);
101-
llvm::BasicBlock *BB = Builder.GetInsertBlock();
102-
llvm::BasicBlock::iterator I = Builder.GetInsertPoint();
103-
if (!BB->empty() && I == BB->end())
104-
Builder.SetCurrentDebugLocation(BB->back().getStableDebugLoc());
105-
}
106-
10795
static bool isValidWorkshareLoopScheduleType(OMPScheduleType SchedType) {
10896
// Valid ordered/unordered and base algorithm combinations.
10997
switch (SchedType & ~OMPScheduleType::MonotonicityMask) {
@@ -163,6 +151,18 @@ static bool isValidWorkshareLoopScheduleType(OMPScheduleType SchedType) {
163151
}
164152
#endif
165153

154+
/// This is wrapper over IRBuilderBase::restoreIP that also restores the current
155+
/// debug location to the last instruction in the specified basic block if the
156+
/// insert point points to the end of the block.
157+
static void restoreIPandDebugLoc(llvm::IRBuilderBase &Builder,
158+
llvm::IRBuilderBase::InsertPoint IP) {
159+
Builder.restoreIP(IP);
160+
llvm::BasicBlock *BB = Builder.GetInsertBlock();
161+
llvm::BasicBlock::iterator I = Builder.GetInsertPoint();
162+
if (!BB->empty() && I == BB->end())
163+
Builder.SetCurrentDebugLocation(BB->back().getStableDebugLoc());
164+
}
165+
166166
static const omp::GV &getGridValue(const Triple &T, Function *Kernel) {
167167
if (T.isAMDGPU()) {
168168
StringRef Features =

llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,3 +3398,146 @@ define <vscale x 4 x double> @vfrec7(<vscale x 4 x float> %a) {
33983398
%2 = call <vscale x 4 x double> @llvm.riscv.vfwmacc(<vscale x 4 x double> poison, <vscale x 4 x float> %a, <vscale x 4 x float> %1, iXLen 7, iXLen 6, iXLen 0)
33993399
ret <vscale x 4 x double> %2
34003400
}
3401+
3402+
define <vscale x 4 x i32> @vandn_vv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {
3403+
; CHECK-LABEL: vandn_vv:
3404+
; CHECK: # %bb.0:
3405+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3406+
; CHECK-NEXT: vandn.vv v10, v8, v10
3407+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3408+
; CHECK-NEXT: vadd.vv v8, v10, v8
3409+
; CHECK-NEXT: ret
3410+
%1 = call <vscale x 4 x i32> @llvm.riscv.vandn.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen -1)
3411+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3412+
ret <vscale x 4 x i32> %2
3413+
}
3414+
3415+
define <vscale x 4 x i32> @vandn_vx(<vscale x 4 x i32> %a, i32 %b, iXLen %vl) {
3416+
; CHECK-LABEL: vandn_vx:
3417+
; CHECK: # %bb.0:
3418+
; CHECK-NEXT: vsetvli a2, zero, e32, m2, ta, ma
3419+
; CHECK-NEXT: vandn.vx v10, v8, a0
3420+
; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma
3421+
; CHECK-NEXT: vadd.vv v8, v10, v8
3422+
; CHECK-NEXT: ret
3423+
%1 = call <vscale x 4 x i32> @llvm.riscv.vandn.nxv4i32.i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, i32 %b, iXLen -1)
3424+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3425+
ret <vscale x 4 x i32> %2
3426+
}
3427+
3428+
define <vscale x 4 x i32> @vbrev_v(<vscale x 4 x i32> %a, iXLen %vl) {
3429+
; CHECK-LABEL: vbrev_v:
3430+
; CHECK: # %bb.0:
3431+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3432+
; CHECK-NEXT: vbrev.v v10, v8
3433+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3434+
; CHECK-NEXT: vadd.vv v8, v10, v8
3435+
; CHECK-NEXT: ret
3436+
%1 = call <vscale x 4 x i32> @llvm.riscv.vbrev.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen -1)
3437+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3438+
ret <vscale x 4 x i32> %2
3439+
}
3440+
3441+
define <vscale x 4 x i32> @vclz_v(<vscale x 4 x i32> %a, iXLen %vl) {
3442+
; CHECK-LABEL: vclz_v:
3443+
; CHECK: # %bb.0:
3444+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3445+
; CHECK-NEXT: vclz.v v10, v8
3446+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3447+
; CHECK-NEXT: vadd.vv v8, v10, v8
3448+
; CHECK-NEXT: ret
3449+
%1 = call <vscale x 4 x i32> @llvm.riscv.vclz.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen -1)
3450+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3451+
ret <vscale x 4 x i32> %2
3452+
}
3453+
3454+
define <vscale x 4 x i32> @vcpop_v(<vscale x 4 x i32> %a, iXLen %vl) {
3455+
; CHECK-LABEL: vcpop_v:
3456+
; CHECK: # %bb.0:
3457+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3458+
; CHECK-NEXT: vcpop.v v10, v8
3459+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3460+
; CHECK-NEXT: vadd.vv v8, v10, v8
3461+
; CHECK-NEXT: ret
3462+
%1 = call <vscale x 4 x i32> @llvm.riscv.vcpopv.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen -1)
3463+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3464+
ret <vscale x 4 x i32> %2
3465+
}
3466+
3467+
define <vscale x 4 x i32> @vctz_v(<vscale x 4 x i32> %a, iXLen %vl) {
3468+
; CHECK-LABEL: vctz_v:
3469+
; CHECK: # %bb.0:
3470+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3471+
; CHECK-NEXT: vctz.v v10, v8
3472+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3473+
; CHECK-NEXT: vadd.vv v8, v10, v8
3474+
; CHECK-NEXT: ret
3475+
%1 = call <vscale x 4 x i32> @llvm.riscv.vctz.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen -1)
3476+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3477+
ret <vscale x 4 x i32> %2
3478+
}
3479+
3480+
define <vscale x 4 x i32> @vror_vv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {
3481+
; CHECK-LABEL: vror_vv:
3482+
; CHECK: # %bb.0:
3483+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3484+
; CHECK-NEXT: vror.vv v10, v8, v10
3485+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3486+
; CHECK-NEXT: vadd.vv v8, v10, v8
3487+
; CHECK-NEXT: ret
3488+
%1 = call <vscale x 4 x i32> @llvm.riscv.vror.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen -1)
3489+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3490+
ret <vscale x 4 x i32> %2
3491+
}
3492+
3493+
define <vscale x 4 x i32> @vror_vx(<vscale x 4 x i32> %a, iXLen %b, iXLen %vl) {
3494+
; CHECK-LABEL: vror_vx:
3495+
; CHECK: # %bb.0:
3496+
; CHECK-NEXT: vsetvli a2, zero, e32, m2, ta, ma
3497+
; CHECK-NEXT: vror.vx v10, v8, a0
3498+
; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma
3499+
; CHECK-NEXT: vadd.vv v8, v10, v8
3500+
; CHECK-NEXT: ret
3501+
%1 = call <vscale x 4 x i32> @llvm.riscv.vror.nxv4i32.iXLen(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen %b, iXLen -1)
3502+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3503+
ret <vscale x 4 x i32> %2
3504+
}
3505+
3506+
define <vscale x 4 x i32> @vror_vi(<vscale x 4 x i32> %a, iXLen %vl) {
3507+
; CHECK-LABEL: vror_vi:
3508+
; CHECK: # %bb.0:
3509+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3510+
; CHECK-NEXT: vror.vi v10, v8, 5
3511+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3512+
; CHECK-NEXT: vadd.vv v8, v10, v8
3513+
; CHECK-NEXT: ret
3514+
%1 = call <vscale x 4 x i32> @llvm.riscv.vror.nxv4i32.iXLen(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen 5, iXLen -1)
3515+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3516+
ret <vscale x 4 x i32> %2
3517+
}
3518+
3519+
define <vscale x 4 x i32> @vrol_vv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {
3520+
; CHECK-LABEL: vrol_vv:
3521+
; CHECK: # %bb.0:
3522+
; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
3523+
; CHECK-NEXT: vrol.vv v10, v8, v10
3524+
; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
3525+
; CHECK-NEXT: vadd.vv v8, v10, v8
3526+
; CHECK-NEXT: ret
3527+
%1 = call <vscale x 4 x i32> @llvm.riscv.vrol.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen -1)
3528+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3529+
ret <vscale x 4 x i32> %2
3530+
}
3531+
3532+
define <vscale x 4 x i32> @vrol_vx(<vscale x 4 x i32> %a, iXLen %b, iXLen %vl) {
3533+
; CHECK-LABEL: vrol_vx:
3534+
; CHECK: # %bb.0:
3535+
; CHECK-NEXT: vsetvli a2, zero, e32, m2, ta, ma
3536+
; CHECK-NEXT: vrol.vx v10, v8, a0
3537+
; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma
3538+
; CHECK-NEXT: vadd.vv v8, v10, v8
3539+
; CHECK-NEXT: ret
3540+
%1 = call <vscale x 4 x i32> @llvm.riscv.vrol.nxv4i32.iXLen(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, iXLen %b, iXLen -1)
3541+
%2 = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %1, <vscale x 4 x i32> %a, iXLen %vl)
3542+
ret <vscale x 4 x i32> %2
3543+
}

0 commit comments

Comments
 (0)