; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 ; RUN: opt -S -passes=dfa-jump-threading -verify-dom-info=1 %s | FileCheck %s declare void @do_something() declare void @user(i32) define void @equivalent_on_default(i1 %c1) { ; CHECK-LABEL: define void @equivalent_on_default( ; CHECK-SAME: i1 [[C1:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[SWITCH_BB:%.*]] ; CHECK: switch_bb: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ] ; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [ ; CHECK-NEXT: i32 0, label [[CASE1:%.*]] ; CHECK-NEXT: i32 1, label [[CASE2:%.*]] ; CHECK-NEXT: ] ; CHECK: switch_bb.jt2: ; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ] ; CHECK-NEXT: br label [[DEFAULT_DEST]] ; CHECK: switch_bb.jt1: ; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ] ; CHECK-NEXT: br label [[CASE2]] ; CHECK: case1: ; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]] ; CHECK: case2: ; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]] ; CHECK: case2then: ; CHECK-NEXT: br label [[CASE2END_JT2]] ; CHECK: case2end: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB]] ; CHECK: case2end.jt2: ; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ] ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]] ; CHECK: default_dest: ; CHECK-NEXT: ret void ; entry: br label %switch_bb switch_bb: %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ] switch i32 %phi, label %default_dest [ i32 0, label %case1 i32 1, label %case2 ] case1: br label %switch_bb case2: br i1 %c1, label %case2then, label %case2end case2then: br label %case2end case2end: %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ] call void @do_something() br label %switch_bb default_dest: ret void } define void @equivalent_on_default_user(i1 %c1) { ; CHECK-LABEL: define void @equivalent_on_default_user( ; CHECK-SAME: i1 [[C1:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[SWITCH_BB:%.*]] ; CHECK: switch_bb: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ] ; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [ ; CHECK-NEXT: i32 0, label [[CASE1:%.*]] ; CHECK-NEXT: i32 1, label [[CASE2:%.*]] ; CHECK-NEXT: ] ; CHECK: switch_bb.jt2: ; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ] ; CHECK-NEXT: br label [[DEFAULT_DEST]] ; CHECK: switch_bb.jt1: ; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ] ; CHECK-NEXT: br label [[CASE2]] ; CHECK: case1: ; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]] ; CHECK: case2: ; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]] ; CHECK: case2then: ; CHECK-NEXT: br label [[CASE2END_JT2]] ; CHECK: case2end: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: call void @user(i32 poison) ; CHECK-NEXT: br label [[SWITCH_BB]] ; CHECK: case2end.jt2: ; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ] ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: call void @user(i32 [[PHI_CASE2_JT2]]) ; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]] ; CHECK: default_dest: ; CHECK-NEXT: ret void ; entry: br label %switch_bb switch_bb: %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ] switch i32 %phi, label %default_dest [ i32 0, label %case1 i32 1, label %case2 ] case1: br label %switch_bb case2: br i1 %c1, label %case2then, label %case2end case2then: br label %case2end case2end: %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ] call void @do_something() call void @user(i32 %phi_case2) br label %switch_bb default_dest: ret void } define void @equivalent_only_cases(i1 %c1) { ; CHECK-LABEL: define void @equivalent_only_cases( ; CHECK-SAME: i1 [[C1:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[SWITCH_BB:%.*]] ; CHECK: switch_bb: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ] ; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [ ; CHECK-NEXT: i32 0, label [[CASE1:%.*]] ; CHECK-NEXT: i32 1, label [[CASE2:%.*]] ; CHECK-NEXT: i32 2, label [[CASE1]] ; CHECK-NEXT: i32 3, label [[CASE1]] ; CHECK-NEXT: ] ; CHECK: switch_bb.jt2: ; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ] ; CHECK-NEXT: br label [[CASE1]] ; CHECK: switch_bb.jt1: ; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ] ; CHECK-NEXT: br label [[CASE2]] ; CHECK: case1: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]] ; CHECK: case2: ; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]] ; CHECK: case2then: ; CHECK-NEXT: br label [[CASE2END_JT2]] ; CHECK: case2end: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB]] ; CHECK: case2end.jt2: ; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ] ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]] ; CHECK: default_dest: ; CHECK-NEXT: ret void ; entry: br label %switch_bb switch_bb: %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ] switch i32 %phi, label %default_dest [ i32 0, label %case1 i32 1, label %case2 i32 2, label %case1 i32 3, label %case1 ] case1: call void @do_something() br label %switch_bb case2: br i1 %c1, label %case2then, label %case2end case2then: br label %case2end case2end: %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ] call void @do_something() br label %switch_bb default_dest: ret void } define void @equivalent_both_case_and_default(i1 %c1, i1 %c2) { ; CHECK-LABEL: define void @equivalent_both_case_and_default( ; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[SWITCH_BB:%.*]] ; CHECK: switch_bb: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ] ; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [ ; CHECK-NEXT: i32 0, label [[CASE1:%.*]] ; CHECK-NEXT: i32 1, label [[CASE2:%.*]] ; CHECK-NEXT: i32 2, label [[CASE1]] ; CHECK-NEXT: i32 3, label [[CASE1]] ; CHECK-NEXT: ] ; CHECK: switch_bb.jt4: ; CHECK-NEXT: [[PHI_JT3:%.*]] = phi i32 [ [[PHI_CASE2_JT3:%.*]], [[CASE2END_JT3:%.*]] ] ; CHECK-NEXT: br label [[DEFAULT_DEST]] ; CHECK: switch_bb.jt2: ; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ] ; CHECK-NEXT: br label [[CASE1]] ; CHECK: switch_bb.jt1: ; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ] ; CHECK-NEXT: br label [[CASE2]] ; CHECK: case1: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]] ; CHECK: case2: ; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]] ; CHECK: case2then: ; CHECK-NEXT: br i1 [[C2]], label [[CASE2THEN2:%.*]], label [[CASE2END_JT2]] ; CHECK: case2then2: ; CHECK-NEXT: br i1 [[C2]], label [[CASE2THEN3:%.*]], label [[CASE2END_JT3]] ; CHECK: case2then3: ; CHECK-NEXT: br label [[CASE2END_JT3]] ; CHECK: case2end: ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB]] ; CHECK: case2end.jt4: ; CHECK-NEXT: [[PHI_CASE2_JT3]] = phi i32 [ 4, [[CASE2THEN2]] ], [ 5, [[CASE2THEN3]] ] ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT3:%.*]] ; CHECK: case2end.jt2: ; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ] ; CHECK-NEXT: call void @do_something() ; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]] ; CHECK: default_dest: ; CHECK-NEXT: ret void ; entry: br label %switch_bb switch_bb: %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ] switch i32 %phi, label %default_dest [ i32 0, label %case1 i32 1, label %case2 i32 2, label %case1 i32 3, label %case1 ] case1: call void @do_something() br label %switch_bb case2: br i1 %c1, label %case2then, label %case2end case2then: br i1 %c2, label %case2then2, label %case2end case2then2: br i1 %c2, label %case2then3, label %case2end case2then3: br label %case2end case2end: %phi_case2 = phi i32 [ 2, %case2 ], [ 3, %case2then ], [ 4, %case2then2 ], [ 5, %case2then3 ] call void @do_something() br label %switch_bb default_dest: ret void }