-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Numerical test for strix compiled with peano (#1077)
The main change here is an update to the pass that unsets the load and store alignments. Now it unsets _all_ llvm.loads and llvm.stores (see comments in pass). Without this, peano tries to scalarize an llvm.load and gets into an infinite/quadratic loop. This PR adds an end-to-end numerical test of peano on strix. One unrelated change in AMDAIELowerToAIE.cpp : while experimenting with adding alignment/noalias attributes to the function signature in function outlining, noticed that the attributes were being dropped in this pass.
- Loading branch information
Showing
11 changed files
with
148 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 0 additions & 70 deletions
70
compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELoadAlignmentReset.cpp
This file was deleted.
Oops, something went wrong.
104 changes: 104 additions & 0 deletions
104
compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELoadStoreAlignmentReset.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2024 The IREE Authors | ||
// | ||
// Licensed 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 "iree-amd-aie/IR/AMDAIEDialect.h" | ||
#include "iree-amd-aie/Transforms/Passes.h" | ||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h" | ||
#include "mlir/Dialect/SCF/Transforms/Transforms.h" | ||
#include "mlir/Dialect/SCF/Utils/Utils.h" | ||
#include "mlir/Pass/Pass.h" | ||
#define DEBUG_TYPE "iree-amdaie-loads-store-alignment-reset" | ||
|
||
namespace mlir::iree_compiler::AMDAIE { | ||
|
||
using namespace mlir; | ||
|
||
namespace { | ||
|
||
/// A pass that removes the alignment attribute from llvm.load and llvm.store | ||
/// operations. As example, this pass will replace | ||
/// | ||
/// ``` | ||
/// %20 = llvm.load %19 {alignment = 1 : i64} : !llvm.ptr -> vector<32xi8> | ||
/// ``` | ||
/// | ||
/// with | ||
/// | ||
/// ``` | ||
/// %20 = llvm.load %19 : !llvm.ptr -> vector<32xi8> | ||
/// ``` | ||
/// | ||
/// The motivation for this is that the alignment on the llvm.load operation, | ||
/// which is assigned in the pass `convert-vector-to-llvm` is currently too | ||
/// conservative and if left as is, results in poor (and sometimes invalid) | ||
/// scalarized code in peano. | ||
/// | ||
/// The pass `convert-vector-to-llvm` does not seem to be doing any analysis to | ||
/// choose the highest possible alignment. It lowers | ||
/// | ||
/// ``` | ||
/// %11 = vector.transfer_read %collapse_shape[%10], %c0_i8 {in_bounds = [true]} | ||
/// : memref<1024xi8>, vector<32xi8> | ||
/// ``` | ||
/// | ||
/// to | ||
/// | ||
/// ``` | ||
/// %20 = llvm.load %19 {alignment = 1 : i64} : !llvm.ptr -> vector<32xi8> | ||
/// ``` | ||
/// | ||
/// even when it can be inferred that %10 is a multiple ot 32. The pass | ||
/// seems to always just use the alignment of the element type. | ||
/// | ||
/// By resetting the alignments that the `convert-vector-to-llvm` pass assigns, | ||
/// the lowering/translation to LLVMIR assigns new alignments. In other words it | ||
/// seems that the translation does not modify existing alignments on llvm.load | ||
/// or llvm.store, but if there is no alignment present it assigns one. | ||
/// | ||
/// Whereas the `convert-vector-to-llvm` pass assigns an alignment based on | ||
/// the element-type, the translation to LLVMIR assigns an alignment based on | ||
/// the vector width. For example, for a vector of 32 i8 values, the alignment | ||
/// assigned is 32. | ||
/// | ||
/// I can imagine cases where the llvm.load actually loads with an alignment | ||
/// less than the vector width, for example if you're loading overlapping | ||
/// vectors (for a convolution say): | ||
/// | ||
/// iteration 1: load bytes 0-8. | ||
/// iteration 2: load bytes 4-12. | ||
/// iteration 3: load bytes 8-16. | ||
/// | ||
/// in this case using the width of the vector (8 bytes) as the alignment would | ||
/// be incorrect, as the loads are only 4-byte aligned. Future work: check if | ||
/// LLVMIR lowering correctly handles this case, if not implement an analysis. | ||
/// | ||
/// See also https://jira.xilinx.com/projects/AIECC/issues/AIECC-589 | ||
|
||
class AMDAIELoadStoreAlignmentReset | ||
: public impl::AMDAIELoadStoreAlignmentResetBase< | ||
AMDAIELoadStoreAlignmentReset> { | ||
void getDependentDialects(DialectRegistry ®istry) const override { | ||
registry.insert<AMDAIEDialect>(); | ||
} | ||
|
||
void runOnOperation() override { | ||
getOperation()->walk([](Operation *op) { | ||
if (auto loadOp = dyn_cast<LLVM::LoadOp>(op)) { | ||
loadOp.setAlignment(std::optional<uint64_t>()); | ||
} else if (auto storeOp = dyn_cast<LLVM::StoreOp>(op)) { | ||
storeOp.setAlignment(std::optional<uint64_t>()); | ||
} | ||
}); | ||
} | ||
}; | ||
|
||
} // namespace | ||
|
||
std::unique_ptr<Pass> createAMDAIELoadStoreAlignmentResetPass() { | ||
return std::make_unique<AMDAIELoadStoreAlignmentReset>(); | ||
} | ||
|
||
} // namespace mlir::iree_compiler::AMDAIE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/test/load_store_alignment_reset.mlir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// RUN: iree-opt --pass-pipeline="builtin.module(func.func(iree-amdaie-load-store-alignment-reset))" %s | FileCheck %s | ||
|
||
|
||
// CHECK-LABEL: func @alignmentsWillBeRemoved(%arg0: !llvm.ptr) | ||
func.func @alignmentsWillBeRemoved(%arg0: !llvm.ptr) { | ||
|
||
// CHECK: %[[L1:.+]] = llvm.load %arg0 : !llvm.ptr -> vector<32xi8> | ||
// CHECK-NEXT: %[[L2:.+]] = llvm.load %arg0 : !llvm.ptr -> vector<32xi8> | ||
// CHECK-NEXT: %[[L4:.+]] = llvm.load %arg0 : !llvm.ptr -> vector<32xi8> | ||
%l1 = llvm.load %arg0 {alignment = 1 : i64} : !llvm.ptr -> vector<32xi8> | ||
%l2 = llvm.load %arg0 {alignment = 2 : i64} : !llvm.ptr -> vector<32xi8> | ||
%l4 = llvm.load %arg0 {alignment = 4 : i64} : !llvm.ptr -> vector<32xi8> | ||
|
||
// CHECK-NEXT: llvm.store %[[L1]], %arg0 : vector<32xi8>, !llvm.ptr | ||
// CHECK-NEXT: llvm.store %[[L1]], %arg0 : vector<32xi8>, !llvm.ptr | ||
// CHECK-NEXT: llvm.store %[[L1]], %arg0 : vector<32xi8>, !llvm.ptr | ||
llvm.store %l1, %arg0 {alignment = 1 : i64} : vector<32xi8>, !llvm.ptr | ||
llvm.store %l1, %arg0 {alignment = 2 : i64} : vector<32xi8>, !llvm.ptr | ||
llvm.store %l1, %arg0 {alignment = 4 : i64} : vector<32xi8>, !llvm.ptr | ||
|
||
// CHECK-NEXT: return | ||
return | ||
} |