Fixes #173180 The crash occurs when a vector constant refines its value during iterative analysis. In `SCCPInstVisitor::visitCastInst`, the logic for folding constants through a `CastInst` uses `markConstant`. This function is strictly designed for initial assignments and contains an assertion that prevents a lattice element from being updated with a different constant pointer. During the analysis of loops or complex data flows, a vector constant may "refine." For example: First Pass: SCCP identifies a value as `<4 x i64> {poison, poison, poison, 0}`. Second Pass: The value refines to `<4 x i64> zeroinitializer`. Because these are distinct `Constant*` objects, `markConstant` triggers a `"Marking constant with different value"` assertion failure. The call to `markConstant` is replaced with `mergeInValue`. Unlike the former, `mergeInValue` is lattice-aware, it allows for valid refinement (moving from a less-defined to a more-defined state) and gracefully handles transitions to Overdefined if a true conflict occurs. This brings BitCast handling in line with how Trunc and Ext instructions are already safely handled in the same pass. Co-authored-by: Milos Poletanovic <mpoletanovic@syrmia.com>
30 lines
1.3 KiB
LLVM
30 lines
1.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
|
|
; RUN: opt -passes=sccp -S < %s | FileCheck %s
|
|
|
|
define <32 x i8> @test(i1 %cond) {
|
|
; CHECK-LABEL: define <32 x i8> @test(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*]]:
|
|
; CHECK-NEXT: br label %[[FOR_COND2:.*]]
|
|
; CHECK: [[FOR_COND2]]:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = phi <4 x i64> [ zeroinitializer, %[[ENTRY]] ], [ splat (i64 1), %[[FOR_COND2]] ]
|
|
; CHECK-NEXT: br i1 [[COND]], label %[[FOR_COND2]], label %[[IF_THEN:.*]]
|
|
; CHECK: [[IF_THEN]]:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> zeroinitializer to <32 x i8>
|
|
; CHECK-NEXT: ret <32 x i8> [[TMP1]]
|
|
;
|
|
entry:
|
|
br label %for.cond2
|
|
|
|
for.cond2: ; preds = %for.cond2, %entry
|
|
%BS_VAR_1.0 = phi <4 x i64> [ <i64 poison, i64 poison, i64 poison, i64 0>, %entry ], [ zeroinitializer, %for.cond2 ]
|
|
%0 = phi <4 x i64> [ zeroinitializer, %entry ], [ splat (i64 1), %for.cond2 ]
|
|
br i1 %cond, label %for.cond2, label %if.then
|
|
|
|
if.then: ; preds = %for.cond2
|
|
%sub = sub <4 x i64> <i64 poison, i64 poison, i64 poison, i64 0>, %BS_VAR_1.0
|
|
%and = and <4 x i64> %0, %sub
|
|
%1 = bitcast <4 x i64> %and to <32 x i8>
|
|
ret <32 x i8> %1
|
|
}
|