Bjorn Pettersson 2d3167f8d8
[SeparateConstOffsetFromGEP] Avoid miscompiles related to trunc nuw/nsw (#154582)
Drop poison generating flags on trunc when distributing trunc over
add/sub/or. We need to do this since for example
(add (trunc nuw A), (trunc nuw B)) is more poisonous than
(trunc nuw (add A, B))).

In some situations it is pessimistic to drop the flags. Such as
if the add in the example above also has the nuw flag. For now we
keep it simple and always drop the flags.

Worth mentioning is that we drop the flags when cloning
instructions and rebuilding the chain. This is done after the
"allowsPreservingNUW" checks in ConstantOffsetExtractor::Extract.
So we still take the "trunc nuw" into consideration when determining
if nuw can be preserved in the gep (which should be ok since that
check also require that all the involved binary operations has nuw).

Fixes #154116
2025-08-22 10:27:57 +02:00

33 lines
1.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 -passes=separate-const-offset-from-gep -S | FileCheck %s
; Verify that we drop "nuw" from trunc.
define ptr @pr154116_nuw(ptr %p, i128 %i) {
; CHECK-LABEL: define ptr @pr154116_nuw(
; CHECK-SAME: ptr [[P:%.*]], i128 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[TMP1:%.*]] = trunc i128 [[I]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[P]], i64 [[TMP1]]
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, ptr [[TMP2]], i64 80
; CHECK-NEXT: ret ptr [[ARRAYIDX2]]
;
%idx = add i128 %i, 20
%idx.conv = trunc nuw i128 %idx to i64
%arrayidx = getelementptr i32, ptr %p, i64 %idx.conv
ret ptr %arrayidx
}
; Verify that we drop "nsw" from trunc.
define ptr @pr154116_nsw(ptr %p, i128 %i) {
; CHECK-LABEL: define ptr @pr154116_nsw(
; CHECK-SAME: ptr [[P:%.*]], i128 [[I:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = trunc i128 [[I]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[P]], i64 [[TMP1]]
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: ret ptr [[ARRAYIDX2]]
;
%idx = add i128 %i, 1
%idx.conv = trunc nsw i128 %idx to i64
%arrayidx = getelementptr i32, ptr %p, i64 %idx.conv
ret ptr %arrayidx
}