Nikita Popov 07292b7203
[LIR][SCEVExpander] Restore original flags when aborting transform (#82362)
SCEVExpanderCleaner will currently remove instructions created by
SCEVExpander, but not restore poison generating flags that it may have
dropped. As such, running LIR can currently spuriously drop flags
without performing any transforms.

Fix this by keeping track of original instruction flags in SCEVExpander.

Fixes https://github.com/llvm/llvm-project/issues/82337.
2024-02-21 10:13:41 +01:00

60 lines
2.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt -S -passes=loop-idiom < %s | FileCheck %s
; The poison flags should be preserved, as no transform takes place.
define void @test(ptr %p.end, ptr %p.start) {
; CHECK-LABEL: define void @test(
; CHECK-SAME: ptr [[P_END:%.*]], ptr [[P_START:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P_END_INT:%.*]] = ptrtoint ptr [[P_END]] to i64
; CHECK-NEXT: [[P_START_INT:%.*]] = ptrtoint ptr [[P_START]] to i64
; CHECK-NEXT: [[DIST:%.*]] = sub nuw i64 [[P_END_INT]], [[P_START_INT]]
; CHECK-NEXT: [[LEN:%.*]] = lshr exact i64 [[DIST]], 5
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P_END]], [[P_START]]
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[PREHEADER:%.*]]
; CHECK: preheader:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[LEN]], [[PREHEADER]] ], [ [[IV_DEC:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_NEG:%.*]] = sub nsw i64 0, [[IV]]
; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [32 x i8], ptr [[P_END]], i64 [[IV_NEG]]
; CHECK-NEXT: [[V:%.*]] = load <4 x i64>, ptr [[SRC]], align 8
; CHECK-NEXT: [[DST:%.*]] = getelementptr inbounds [32 x i8], ptr [[P_START]], i64 [[IV_NEG]]
; CHECK-NEXT: store <4 x i64> [[V]], ptr [[DST]], align 8
; CHECK-NEXT: [[IV_DEC]] = add i64 [[IV]], -1
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[IV_DEC]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_EXIT:%.*]], label [[LOOP]]
; CHECK: loop.exit:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
%p.end.int = ptrtoint ptr %p.end to i64
%p.start.int = ptrtoint ptr %p.start to i64
%dist = sub nuw i64 %p.end.int, %p.start.int
%len = lshr exact i64 %dist, 5
%cmp = icmp eq ptr %p.end, %p.start
br i1 %cmp, label %exit, label %preheader
preheader:
br label %loop
loop:
%iv = phi i64 [ %len, %preheader ], [ %iv.dec, %loop ]
%iv.neg = sub nsw i64 0, %iv
%src = getelementptr inbounds [32 x i8], ptr %p.end, i64 %iv.neg
%v = load <4 x i64>, ptr %src, align 8
%dst = getelementptr inbounds [32 x i8], ptr %p.start, i64 %iv.neg
store <4 x i64> %v, ptr %dst, align 8
%iv.dec = add i64 %iv, -1
%cmp2 = icmp eq i64 %iv.dec, 0
br i1 %cmp2, label %loop.exit, label %loop
loop.exit:
br label %exit
exit:
ret void
}