Index: llvm/lib/Transforms/Utils/SCCPSolver.cpp =================================================================== --- llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -612,6 +612,7 @@ void visitCastInst(CastInst &I); void visitSelectInst(SelectInst &I); void visitUnaryOperator(Instruction &I); + void visitFreezeInst(FreezeInst &I); void visitBinaryOperator(Instruction &I); void visitCmpInst(CmpInst &I); void visitExtractValueInst(ExtractValueInst &EVI); @@ -1397,6 +1398,24 @@ markOverdefined(&I); } +void SCCPInstVisitor::visitFreezeInst(FreezeInst &I) { + ValueLatticeElement V0State = getValueState(I.getOperand(0)); + ValueLatticeElement &IV = ValueState[&I]; + // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would + // discover a concrete value later. + if (SCCPSolver::isOverdefined(IV)) + return (void)markOverdefined(&I); + + // If something is unknown/undef, wait for it to resolve. + if (V0State.isUnknownOrUndef()) + return; + + if (SCCPSolver::isConstant(V0State)) + return (void)markConstant(IV, &I, getConstant(V0State)); + + markOverdefined(&I); +} + // Handle Binary Operators. void SCCPInstVisitor::visitBinaryOperator(Instruction &I) { ValueLatticeElement V1State = getValueState(I.getOperand(0)); Index: llvm/test/Transforms/SCCP/freeze.ll =================================================================== --- llvm/test/Transforms/SCCP/freeze.ll +++ llvm/test/Transforms/SCCP/freeze.ll @@ -39,6 +39,38 @@ ret <2 x i32> %fr } +define i1 @freeze_const_i1() { +; CHECK-LABEL: @freeze_const_i1( +; CHECK-NEXT: ret i1 true +; + %fr = freeze i1 1 + ret i1 %fr +} + +define ptr @freeze_const_ptr() { +; CHECK-LABEL: @freeze_const_ptr( +; CHECK-NEXT: ret ptr inttoptr (i32 256 to ptr) +; + %fr = freeze ptr inttoptr (i32 256 to ptr) + ret ptr %fr +} + +define float @freeze_const_float() { +; CHECK-LABEL: @freeze_const_float( +; CHECK-NEXT: ret float 2.500000e-01 +; + %fr = freeze float 2.500000e-01 + ret float %fr +} + +define <2 x i32> @freeze_const_vector() { +; CHECK-LABEL: @freeze_const_vector( +; CHECK-NEXT: ret <2 x i32> +; + %fr = freeze <2 x i32> + ret <2 x i32> %fr +} + define i1 @propagate_range_from_and_through_freeze(i32 %x, i32 %y) { ; CHECK-LABEL: @propagate_range_from_and_through_freeze( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3