
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.
60 lines
2.3 KiB
LLVM
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
|
|
}
|