mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
522d679e59
As reported in https://reviews.llvm.org/D83101#2133062 the new visitInsertElementInst()/visitExtractElementInst() functionality is causing miscompiles (previously-crashing test added) It is due to the fact how the infra of Scalarizer is dealing with DCE, it was not updated or was it ready for such scalar value forwarding. It always assumed that the moment we "scalarized" something, it can go away, and did so with prejudice. But that is no longer safe/okay to do. Instead, let's prevent it from ever shooting itself into foot, and let's just accumulate the instructions-to-be-deleted in a vector, and collectively cleanup (those that are *actually* dead) them all at the end. All existing tests are not reporting any new garbage leftovers, but maybe it's test coverage issue.
91 lines
3.8 KiB
LLVM
91 lines
3.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -scalarizer -S -o - | FileCheck %s
|
|
|
|
define i16 @f1() {
|
|
; CHECK-LABEL: @f1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_END:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[INSERT:%.*]] = insertelement <4 x i16> [[INSERT]], i16 ptrtoint (i16 ()* @f1 to i16), i32 0
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: br i1 undef, label [[FOR_BODY:%.*]], label [[FOR_END]]
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: [[EXTRACT:%.*]] = phi i16 [ 1, [[ENTRY:%.*]] ], [ undef, [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i16 [[EXTRACT]]
|
|
;
|
|
entry:
|
|
br label %for.end
|
|
|
|
for.body:
|
|
%insert = insertelement <4 x i16> %insert, i16 ptrtoint (i16 () * @f1 to i16), i32 0
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
br i1 undef, label %for.body, label %for.end
|
|
|
|
for.end:
|
|
; opt used to hang when scalarizing this code. When scattering %insert we
|
|
; need to analyze the insertelement in the unreachable-from-entry block
|
|
; for.body. Note that the insertelement instruction depends on itself, and
|
|
; this kind of IR is not allowed in reachable-from-entry blocks.
|
|
%phi = phi <4 x i16> [ <i16 1, i16 1, i16 1, i16 1>, %entry ], [ %insert, %for.cond ]
|
|
%extract = extractelement <4 x i16> %phi, i32 0
|
|
ret i16 %extract
|
|
}
|
|
|
|
define void @f2() {
|
|
; CHECK-LABEL: @f2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_END8:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: br label [[IF_END8]]
|
|
; CHECK: for.body2:
|
|
; CHECK-NEXT: br i1 undef, label [[FOR_END:%.*]], label [[FOR_INC:%.*]]
|
|
; CHECK: for.end:
|
|
; CHECK-NEXT: br label [[FOR_INC]]
|
|
; CHECK: for.inc:
|
|
; CHECK-NEXT: [[E_SROA_3_2:%.*]] = phi <2 x i64> [ <i64 1, i64 1>, [[FOR_END]] ], [ [[E_SROA_3_2]], [[FOR_BODY2:%.*]] ]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 6, [[FOR_END]] ], [ [[TMP0]], [[FOR_BODY2]] ]
|
|
; CHECK-NEXT: br i1 undef, label [[FOR_BODY2]], label [[FOR_COND1_FOR_END7_CRIT_EDGE:%.*]]
|
|
; CHECK: for.cond1.for.end7_crit_edge:
|
|
; CHECK-NEXT: br label [[IF_END8]]
|
|
; CHECK: if.end8:
|
|
; CHECK-NEXT: [[E_SROA_3_4_I0:%.*]] = phi i64 [ undef, [[FOR_BODY]] ], [ undef, [[FOR_COND1_FOR_END7_CRIT_EDGE]] ], [ undef, [[IF_THEN]] ]
|
|
; CHECK-NEXT: [[E_SROA_3_4_I1:%.*]] = phi i64 [ undef, [[FOR_BODY]] ], [ undef, [[FOR_COND1_FOR_END7_CRIT_EDGE]] ], [ undef, [[IF_THEN]] ]
|
|
; CHECK-NEXT: br label [[FOR_BODY]]
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %if.end8, %entry
|
|
br i1 undef, label %if.then, label %if.end8
|
|
|
|
if.then: ; preds = %for.body
|
|
br label %if.end8
|
|
|
|
for.body2: ; preds = %for.inc
|
|
br i1 undef, label %for.end, label %for.inc
|
|
|
|
for.end: ; preds = %for.body2
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %for.end, %for.body2
|
|
%e.sroa.3.2 = phi <2 x i64> [ <i64 1, i64 1>, %for.end ], [ %e.sroa.3.2, %for.body2 ]
|
|
%0 = phi i32 [ 6, %for.end ], [ %0, %for.body2 ]
|
|
br i1 undef, label %for.body2, label %for.cond1.for.end7_crit_edge
|
|
|
|
for.cond1.for.end7_crit_edge: ; preds = %for.inc
|
|
br label %if.end8
|
|
|
|
if.end8: ; preds = %for.cond1.for.end7_crit_edge, %if.then, %for.body
|
|
; This used to lead to inserted extractelement instructions between the phis
|
|
; in %for.inc.
|
|
; %e.sroa.3.2 is defined in a block that is unreachable from entry so we can
|
|
; safely replace it with undef in the phi defining e.sroa.3.4.
|
|
%e.sroa.3.4 = phi <2 x i64> [ undef, %for.body ], [ %e.sroa.3.2, %for.cond1.for.end7_crit_edge ], [ undef, %if.then ]
|
|
br label %for.body
|
|
}
|