[PATCH] D125009: [ArgPromotion] Use common alignment for loads in caller

Pavel Samolysov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 5 06:01:17 PDT 2022


psamolysov created this revision.
psamolysov added reviewers: nikic, aeubanks, jdoerfert.
psamolysov added a project: LLVM.
Herald added subscribers: ormris, hiraditya.
Herald added a project: All.
psamolysov requested review of this revision.
Herald added a subscriber: llvm-commits.

In byval promotion, the generated in callers 'load' instructions have
the common alignment with the corresponding offset and alignment of
the promoted byval argument:

define internal void @callee_load_first_element(%struct.ss* byval(%struct.ss) align 16 %b) {

  %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
  ...

}

will be optimized into:

define internal void @callee_load_from_aligned_1(i32 %b.0.val) {

  %temp2 = add i32 %b.0.val, 1
  ret void

}

define i32 @caller_load_first_element() {

  %S = alloca %struct.ss, align 16

...

  %S.0 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0
  %S.0.val = load i32, i32* %S.0, align 16
  %S.1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1
  %S.1.val = load i64, i64* %S.1, align 4
  call void @callee_load_first_element(i32 %S.0.val, i64 %S.1.val)

...
}

(So, '%S.0.val' has 'align 16', the same align as the initial
'%struct.ss' argument has.)

But the "usual" promotion doesn't follow this rule, the corresponding
'load' instruction generated in the caller will have just the maximum
alignment of all the loads for the argument's part in the callee, and
the possible alignment for the argument itself is just ignored:

define internal void @callee_load_from_aligned(%struct.ss* align 16 %b) {

  %temp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
  %temp1 = load i32, i32* %temp, align 4
  %temp2 = add i32 %temp1, 1
  %temp3 = load i32, i32* %temp, align 8
  ret void

}

will be optimized into:

define internal void @callee_load_from_aligned(i32 %b.0.val) {

  %temp2 = add i32 %b.0.val, 1
  ret void

}

define i32 @caller_load_from_aligned() {

  %S = alloca %struct.ss, align 16

...

  %1 = getelementptr %struct.ss, %struct.ss* %S, i64 0, i32 0
  %S.val = load i32, i32* %1, align 8
  call void @callee_load_from_aligned_1(i32 %S.val)

...
}

(So, '%S.val' has 'align 8' while the pointer, argument '%b' in the
callee, is aligned by 16.)

The intent of the patch is to align the behavior of both propagation
schemes: byval and non-byval. However, if there is a load with a larger
value of the 'align' attribute than the argument has, the non-byval
promotion will use this alignment while the byval one doesn't.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125009

Files:
  llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
  llvm/test/Transforms/ArgumentPromotion/align.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125009.427291.patch
Type: text/x-patch
Size: 7778 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220505/16af0eb1/attachment.bin>


More information about the llvm-commits mailing list