Skip to content

Commit 3bd2d07

Browse files
committed
[llvm] Optimize MachineMemOperand::getAlign with KnownBits information
When using the `align_value` attribute, the original getAlign calculation (BaseAlign + Offset) cannot capture more precise alignment information after the load/store legalization phases (specifically after `expandUnalignedLoad`/`expandUnalignedStore` generate new load/store instructions). Fixes#143215
1 parent 97ac648 commit 3bd2d07

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

llvm/lib/CodeGen/MachineOperand.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ADT/StableHashing.h"
1515
#include "llvm/ADT/StringExtras.h"
1616
#include "llvm/Analysis/Loads.h"
17+
#include "llvm/Analysis/ValueTracking.h"
1718
#include "llvm/CodeGen/MIRFormatter.h"
1819
#include "llvm/CodeGen/MachineFrameInfo.h"
1920
#include "llvm/CodeGen/MachineJumpTableInfo.h"
@@ -1136,7 +1137,20 @@ void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
11361137
/// getAlign - Return the minimum known alignment in bytes of the
11371138
/// actual memory reference.
11381139
Align MachineMemOperand::getAlign() const {
1139-
return commonAlignment(getBaseAlign(), getOffset());
1140+
Align RetAlign = commonAlignment(getBaseAlign(), getOffset());
1141+
if (const Value *V = getValue()) {
1142+
if (auto *I = dyn_cast<Instruction>(V)) {
1143+
DataLayout DL = I->getDataLayout();
1144+
unsigned PtrWidth = DL.getPointerTypeSizeInBits(V->getType());
1145+
KnownBits Known(PtrWidth);
1146+
llvm::computeKnownBits(V, Known, DL);
1147+
Known = KnownBits::add(
1148+
Known, KnownBits::makeConstant(APInt(PtrWidth, getOffset())));
1149+
unsigned AlignBits = Known.countMinTrailingZeros();
1150+
RetAlign = std::max(Align(1ull << std::min(31U, AlignBits)), RetAlign);
1151+
}
1152+
}
1153+
return RetAlign;
11401154
}
11411155

11421156
void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11848,6 +11848,10 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1184811848
OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(),
1184911849
OutVal, SDNoFPClass);
1185011850
}
11851+
if (Arg.hasAttribute(Attribute::Alignment)) {
11852+
OutVal =
11853+
DAG.getAssertAlign(dl, OutVal, Arg.getParamAlign().valueOrOne());
11854+
}
1185111855
ArgValues.push_back(OutVal);
1185211856
}
1185311857

llvm/test/CodeGen/RISCV/unaligned-load-store.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,5 +578,24 @@ define void @store_large_constant(ptr %x) {
578578
store i64 18364758544493064720, ptr %x, align 1
579579
ret void
580580
}
581+
582+
define void @store_const_with_align_attribute(ptr align 2 %p) {
583+
; SLOW-LABEL: store_const_with_align_attribute:
584+
; SLOW: # %bb.0: # %entry
585+
; SLOW-NEXT: sb zero, 3(a0)
586+
; SLOW-NEXT: sh zero, 4(a0)
587+
; SLOW-NEXT: sb zero, 6(a0)
588+
; SLOW-NEXT: ret
589+
;
590+
; FAST-LABEL: store_const_with_align_attribute:
591+
; FAST: # %bb.0: # %entry
592+
; FAST-NEXT: sw zero, 3(a0)
593+
; FAST-NEXT: ret
594+
entry:
595+
%len = getelementptr inbounds nuw i8, ptr %p, i32 3
596+
store i32 0, ptr %len, align 1
597+
ret void
598+
}
599+
581600
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
582601
; SLOWZBKB: {{.*}}

0 commit comments

Comments
 (0)