Files
clang-p2996/llvm/test/Transforms/InstCombine/phi-select-constant.ll
Sanjay Patel 4f051fe374 [InstCombine] avoid crash sinking to unreachable block
The test is reduced from the example in D82005.

Similar to 94f6d365e, the test here would assert in
the DomTree when we tried to convert a select to a
phi with an unreachable block operand.

We may want to add some kind of guard code in DomTree
itself to avoid this sort of problem.
2020-12-10 13:10:26 -05:00

161 lines
4.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -S -instcombine | FileCheck %s
@A = extern_weak global i32, align 4
@B = extern_weak global i32, align 4
define i32 @foo(i1 %which) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
; CHECK: delay:
; CHECK-NEXT: br label [[FINAL]]
; CHECK: final:
; CHECK-NEXT: [[USE2:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ select (i1 icmp eq (i32* @A, i32* @B), i32 2, i32 1), [[DELAY]] ]
; CHECK-NEXT: ret i32 [[USE2]]
;
entry:
br i1 %which, label %final, label %delay
delay:
br label %final
final:
%use2 = phi i1 [ false, %entry ], [ icmp eq (i32* @A, i32* @B), %delay ]
%value = select i1 %use2, i32 2, i32 1
ret i32 %value
}
; test folding of select into phi for vectors.
define <4 x i64> @vec1(i1 %which) {
; CHECK-LABEL: @vec1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
; CHECK: delay:
; CHECK-NEXT: br label [[FINAL]]
; CHECK: final:
; CHECK-NEXT: [[PHINODE:%.*]] = phi <4 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ <i64 0, i64 0, i64 126, i64 127>, [[DELAY]] ]
; CHECK-NEXT: ret <4 x i64> [[PHINODE]]
;
entry:
br i1 %which, label %final, label %delay
delay:
br label %final
final:
%phinode = phi <4 x i1> [ <i1 true, i1 true, i1 true, i1 true>, %entry ], [ <i1 true, i1 true, i1 false, i1 false>, %delay ]
%sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64> <i64 124, i64 125, i64 126, i64 127>
ret <4 x i64> %sel
}
define <4 x i64> @vec2(i1 %which) {
; CHECK-LABEL: @vec2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
; CHECK: delay:
; CHECK-NEXT: br label [[FINAL]]
; CHECK: final:
; CHECK-NEXT: [[PHINODE:%.*]] = phi <4 x i64> [ <i64 124, i64 125, i64 126, i64 127>, [[ENTRY:%.*]] ], [ <i64 0, i64 125, i64 0, i64 127>, [[DELAY]] ]
; CHECK-NEXT: ret <4 x i64> [[PHINODE]]
;
entry:
br i1 %which, label %final, label %delay
delay:
br label %final
final:
%phinode = phi <4 x i1> [ <i1 false, i1 false, i1 false, i1 false>, %entry ], [ <i1 true, i1 false, i1 true, i1 false>, %delay ]
%sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64> <i64 124, i64 125, i64 126, i64 127>
ret <4 x i64> %sel
}
; Test PR33364
; Insert the generated select into the same block as the incoming phi value.
; phi has constant vectors along with a single non-constant vector as operands.
define <2 x i8> @vec3(i1 %cond1, i1 %cond2, <2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {
; CHECK-LABEL: @vec3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[PHI_SEL1:%.*]] = shufflevector <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 3>
; CHECK-NEXT: br i1 [[COND1:%.*]], label [[IF1:%.*]], label [[ELSE:%.*]]
; CHECK: if1:
; CHECK-NEXT: [[PHI_SEL2:%.*]] = shufflevector <2 x i8> [[Y]], <2 x i8> [[Z]], <2 x i32> <i32 0, i32 3>
; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF2:%.*]], label [[ELSE]]
; CHECK: if2:
; CHECK-NEXT: [[PHI_SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> [[Y]], <2 x i8> [[Z]]
; CHECK-NEXT: br label [[ELSE]]
; CHECK: else:
; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i8> [ [[PHI_SEL]], [[IF2]] ], [ [[PHI_SEL1]], [[ENTRY:%.*]] ], [ [[PHI_SEL2]], [[IF1]] ]
; CHECK-NEXT: ret <2 x i8> [[PHI]]
;
entry:
br i1 %cond1, label %if1, label %else
if1:
br i1 %cond2, label %if2, label %else
if2:
br label %else
else:
%phi = phi <2 x i1> [ %x, %if2 ], [ <i1 0, i1 1>, %entry ], [ <i1 1, i1 0>, %if1 ]
%sel = select <2 x i1> %phi, <2 x i8> %y, <2 x i8> %z
ret <2 x i8> %sel
}
; Don't crash on unreachable IR.
define void @PR48369(i32 %a, i32* %p) {
; CHECK-LABEL: @PR48369(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[PHI_CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ [[PHI_CMP]], [[DEADBB:%.*]] ], [ true, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SHL:%.*]] = select i1 [[CMP]], i32 256, i32 0
; CHECK-NEXT: store i32 [[SHL]], i32* [[P:%.*]], align 4
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: deadbb:
; CHECK-NEXT: br label [[BB1]]
; CHECK: end:
; CHECK-NEXT: ret void
;
entry:
%phi.cmp = icmp sgt i32 %a, 0
br label %bb1
bb1:
%cmp = phi i1 [ %phi.cmp, %deadbb ], [ true, %entry ]
%shl = select i1 %cmp, i32 256, i32 0
store i32 %shl, i32* %p
br label %end
deadbb:
br label %bb1
end:
ret void
}
define i16 @sink_to_unreachable_crash(i1 %a) {
; CHECK-LABEL: @sink_to_unreachable_crash(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = select i1 [[A:%.*]], i16 0, i16 5
; CHECK-NEXT: br label [[INF_LOOP:%.*]]
; CHECK: inf_loop:
; CHECK-NEXT: br label [[INF_LOOP]]
; CHECK: unreachable:
; CHECK-NEXT: ret i16 [[S]]
;
entry:
%s = select i1 %a, i16 0, i16 5
br label %inf_loop
inf_loop:
br label %inf_loop
unreachable: ; No predecessors!
ret i16 %s
}