The vector combiner will process all instructions as it first loops through the function, adding any newly added and deleted instructions to a worklist which is then processed when all nodes are done. These leaves extra uses in the graph as the initial processing is performed, leading to sub-optimal decisions being made for other combines. This changes it so that trivially dead instructions are removed immediately. The main changes that this requires is to make sure iterator invalidation does not occur.
40 lines
1.8 KiB
LLVM
40 lines
1.8 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: [[E0:%.*]] = load i32, ptr [[VP]], 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
|
|
}
|
|
|
|
; infinite loop if we fold an extract that is waiting to be erased
|
|
define void @unused_extract(ptr %p) {
|
|
; CHECK-LABEL: @unused_extract(
|
|
; CHECK-NEXT: [[LOAD:%.*]] = load <4 x float>, ptr [[P:%.*]], align 8
|
|
; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[LOAD]], i64 1
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%load = load <4 x float>, ptr %p, align 8
|
|
%shuffle0 = shufflevector <4 x float> zeroinitializer, <4 x float> %load, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
|
|
%shuffle1 = shufflevector <4 x float> %shuffle0, <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 4, i32 poison, i32 poison>
|
|
%extract = extractelement <4 x float> %load, i64 1
|
|
ret void
|
|
}
|