
scalarizeLoadExtract replaces instructions up the use list, which can result in the vectorcombine worklist adding users back to the worklist when they should really be erased first.
27 lines
1.3 KiB
LLVM
27 lines
1.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s
|
|
; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s
|
|
|
|
; infinite loop if we add the erased instructions to the work list in the wrong order.
|
|
define void @multiple_extract(ptr %p) {
|
|
; CHECK-LABEL: @multiple_extract(
|
|
; CHECK-NEXT: [[VP:%.*]] = load ptr, ptr [[P:%.*]], align 8
|
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <2 x i32>, ptr [[VP]], i32 0, i64 0
|
|
; CHECK-NEXT: [[E0:%.*]] = load i32, ptr [[TMP1]], align 16
|
|
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <2 x i32>, ptr [[VP]], i32 0, i64 1
|
|
; CHECK-NEXT: [[E1:%.*]] = load i32, ptr [[TMP2]], align 4
|
|
; CHECK-NEXT: store i32 [[E0]], ptr [[P]], align 4
|
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 4
|
|
; CHECK-NEXT: store i32 [[E1]], ptr [[P1]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%vp = load ptr, ptr %p, align 8
|
|
%v = load <2 x i32>, ptr %vp, align 16
|
|
%e0 = extractelement <2 x i32> %v, i64 0
|
|
%e1 = extractelement <2 x i32> %v, i64 1
|
|
store i32 %e0, ptr %p, align 4
|
|
%p1 = getelementptr inbounds nuw i8, ptr %p, i64 4
|
|
store i32 %e1, ptr %p1, align 4
|
|
ret void
|
|
}
|