; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -codegenprepare < %s | FileCheck %s target triple = "x86_64-unknown-linux-gnu" define void @f1(i32 %a) { ; CHECK-LABEL: @f1( ; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[A:%.*]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[FR]], 0 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %c = icmp eq i32 %a, 0 %fr = freeze i1 %c br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @f2(i32 %a) { ; CHECK-LABEL: @f2( ; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[A:%.*]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, [[FR]] ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %c = icmp eq i32 0, %a %fr = freeze i1 %c br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @f3(i32 %a) { ; CHECK-LABEL: @f3( ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, 1 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %c = icmp eq i32 0, 1 %fr = freeze i1 %c br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define i1 @ptrcmp(i8* %p) { ; CHECK-LABEL: @ptrcmp( ; CHECK-NEXT: [[FR:%.*]] = freeze i8* [[P:%.*]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[FR]], null ; CHECK-NEXT: ret i1 [[C]] ; %c = icmp eq i8* %p, null %fr = freeze i1 %c ret i1 %fr } define i1 @fcmp(float %a) { ; CHECK-LABEL: @fcmp( ; CHECK-NEXT: [[FR:%.*]] = freeze float [[A:%.*]] ; CHECK-NEXT: [[C:%.*]] = fcmp oeq float [[FR]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[C]] ; %c = fcmp oeq float %a, 0.0 %fr = freeze i1 %c ret i1 %fr } define i1 @fcmp_nan(float %a) { ; CHECK-LABEL: @fcmp_nan( ; CHECK-NEXT: [[C:%.*]] = fcmp nnan oeq float [[A:%.*]], 0.000000e+00 ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[C]] ; CHECK-NEXT: ret i1 [[FR]] ; %c = fcmp nnan oeq float %a, 0.0 %fr = freeze i1 %c ret i1 %fr } define void @and_bitmask(i32 %flag) { ; CHECK-LABEL: @and_bitmask( ; CHECK-NEXT: [[V:%.*]] = and i32 [[FLAG:%.*]], 1 ; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[V]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[FR]], 0 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %v = and i32 %flag, 1 %c = icmp eq i32 %v, 0 %fr = freeze i1 %c br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and_bitmask_r(i32 %flag) { ; CHECK-LABEL: @and_bitmask_r( ; CHECK-NEXT: [[V:%.*]] = and i32 1, [[FLAG:%.*]] ; CHECK-NEXT: [[FR:%.*]] = freeze i32 [[V]] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, [[FR]] ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %v = and i32 1, %flag %c = icmp eq i32 0, %v %fr = freeze i1 %c br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and_bitmask2(i32 %flag, i32 %flag2) { ; CHECK-LABEL: @and_bitmask2( ; CHECK-NEXT: [[V:%.*]] = and i32 [[FLAG:%.*]], 1 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[V]], 0 ; CHECK-NEXT: [[V2:%.*]] = and i32 [[FLAG2:%.*]], 2 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[V2]], 0 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[C]], [[C2]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[COND]] ; CHECK-NEXT: br i1 [[FR]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %v = and i32 %flag, 1 %c = icmp eq i32 %v, 0 %v2 = and i32 %flag2, 2 %c2 = icmp eq i32 %v2, 0 %cond = or i1 %c, %c2 %fr = freeze i1 %cond br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @and( ; CHECK-NEXT: [[COND:%.*]] = and i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[COND2:%.*]] = and i1 [[C:%.*]], [[COND]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[COND2]] ; CHECK-NEXT: br i1 [[FR]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %cond = and i1 %a, %b %cond2 = and i1 %c, %cond %fr = freeze i1 %cond2 br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and_long(i1 %a, i1 %b, i1 %c, i1 %d, i1 %e, i1 %f, i1 %g) { ; CHECK-LABEL: @and_long( ; CHECK-NEXT: [[COND:%.*]] = and i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[COND2:%.*]] = and i1 [[C:%.*]], [[COND]] ; CHECK-NEXT: [[COND3:%.*]] = and i1 [[D:%.*]], [[COND2]] ; CHECK-NEXT: [[COND4:%.*]] = and i1 [[E:%.*]], [[COND3]] ; CHECK-NEXT: [[COND5:%.*]] = and i1 [[F:%.*]], [[COND4]] ; CHECK-NEXT: [[COND6:%.*]] = and i1 [[G:%.*]], [[COND5]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[COND6]] ; CHECK-NEXT: br i1 [[FR]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %cond = and i1 %a, %b %cond2 = and i1 %c, %cond %cond3 = and i1 %d, %cond2 %cond4 = and i1 %e, %cond3 %cond5 = and i1 %f, %cond4 %cond6 = and i1 %g, %cond5 %fr = freeze i1 %cond6 br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and_cmp(i32 %v, float %w, i32 %v2) { ; CHECK-LABEL: @and_cmp( ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[V:%.*]], 0 ; CHECK-NEXT: [[C2:%.*]] = fcmp oeq float [[W:%.*]], 0.000000e+00 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[C1]], [[C2]] ; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[V2:%.*]], 1 ; CHECK-NEXT: [[COND2:%.*]] = and i1 [[COND]], [[C3]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[COND2]] ; CHECK-NEXT: br i1 [[FR]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %c1 = icmp eq i32 %v, 0 %c2 = fcmp oeq float %w, 0.0 %cond = and i1 %c1, %c2 %c3 = icmp eq i32 %v2, 1 %cond2 = and i1 %cond, %c3 %fr = freeze i1 %cond2 br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @or(i1 %a, i1 %b, i1 %c) { ; CHECK-LABEL: @or( ; CHECK-NEXT: [[COND:%.*]] = or i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[COND2:%.*]] = or i1 [[C:%.*]], [[COND]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[COND2]] ; CHECK-NEXT: br i1 [[FR]], label [[A:%.*]], label [[B:%.*]] ; CHECK: A: ; CHECK-NEXT: call void @g1() ; CHECK-NEXT: ret void ; CHECK: B: ; CHECK-NEXT: call void @g2() ; CHECK-NEXT: ret void ; %cond = or i1 %a, %b %cond2 = or i1 %c, %cond %fr = freeze i1 %cond2 br i1 %fr, label %A, label %B A: call void @g1() ret void B: call void @g2() ret void } define void @and_loop(i1 %a, i1 %b) { ; CHECK-LABEL: @and_loop( ; CHECK-NEXT: ret void ; CHECK: UNREACHABLE: ; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], [[C]] ; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[C]] ; CHECK-NEXT: br i1 [[FR]], label [[UNREACHABLE:%.*]], label [[EXIT:%.*]] ; CHECK: EXIT: ; CHECK-NEXT: ret void ; ret void UNREACHABLE: %c = and i1 %a, %c %fr = freeze i1 %c br i1 %fr, label %UNREACHABLE, label %EXIT EXIT: ret void } declare void @g1() declare void @g2()