diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -322,6 +322,16 @@ } void visitFenceInst(FenceInst &I) { /*returns void*/ } + void visitFreezeInst(FreezeInst &I) { + auto &OpV = getValueState(I.getOperand(0)); + // If the operand is known to be undef, wait until it changes. If it stays + // undef until the end of solving, resolvedUndefsIn will handle it. + if (OpV.isUndef()) + return; + + auto &LV = getValueState(&I); + mergeInValue(LV, &I, OpV); + } void visitInstruction(Instruction &I); diff --git a/llvm/test/Transforms/SCCP/freeze.ll b/llvm/test/Transforms/SCCP/freeze.ll --- a/llvm/test/Transforms/SCCP/freeze.ll +++ b/llvm/test/Transforms/SCCP/freeze.ll @@ -43,17 +43,12 @@ ; CHECK-LABEL: @propagate_range_from_and_through_freeze( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 ; CHECK-NEXT: [[AND_FR:%.*]] = freeze i32 [[AND]] -; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[AND_FR]], 100 -; CHECK-NEXT: call void @use(i1 [[F_1]]) -; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[AND_FR]], 3 -; CHECK-NEXT: call void @use(i1 [[T_1]]) -; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[AND_FR]], 3 -; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[AND_FR]], [[Y:%.*]] ; CHECK-NEXT: call void @use(i1 [[C_1]]) -; CHECK-NEXT: [[R_1:%.*]] = xor i1 [[T_1]], [[F_1]] -; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[F_2]] -; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_1]] +; CHECK-NEXT: [[R_3:%.*]] = xor i1 true, [[C_1]] ; CHECK-NEXT: ret i1 [[R_3]] ; %and = and i32 %x, 3 @@ -84,10 +79,7 @@ ; CHECK: exit: ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 10, [[TRUE_1]] ], [ 20, [[TRUE_2]] ], [ undef, [[FALSE]] ] ; CHECK-NEXT: [[P_FR:%.*]] = freeze i32 [[P]] -; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[P_FR]], 20 -; CHECK-NEXT: [[T_2:%.*]] = icmp uge i32 [[P_FR]], 10 -; CHECK-NEXT: [[RES:%.*]] = xor i1 [[T_1]], [[T_2]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 false ; br i1 %c.1, label %true.1, label %false