Index: llvm/lib/Transforms/Utils/SCCPSolver.cpp =================================================================== --- llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -288,7 +288,7 @@ void visitSelectInst(SelectInst &I); void visitUnaryOperator(Instruction &I); void visitBinaryOperator(Instruction &I); - void visitCmpInst(CmpInst &I); + void visitCmpInst(Instruction &I); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); @@ -1020,8 +1020,9 @@ // point types, like and <4 x i32> overdefined, zeroinitializer. } -// Handle ICmpInst instruction. -void SCCPInstVisitor::visitCmpInst(CmpInst &I) { +// Handle ICmpInst and FCmpInst instruction. +void SCCPInstVisitor::visitCmpInst(Instruction &I) { + assert((isa(I) || isa(I)) && "Wrong class of Instruction!"); // Do not cache this lookup, getValueState calls later in the function might // invalidate the reference. if (isOverdefined(ValueState[&I])) @@ -1035,7 +1036,16 @@ auto V1State = getValueState(Op1); auto V2State = getValueState(Op2); - Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State); + FCmpInst::Predicate IPred; + if (isa(I)) { + CmpInst *CI = cast(&I); + IPred = CI->getPredicate(); + } + else { + ConstrainedFPCmpIntrinsic *CCI = cast(&I); + IPred = CCI->getPredicate(); + } + Constant *C = V1State.getCompare(IPred, I.getType(), V2State); if (C) { // TODO: getCompare() currently has incorrect handling for unknown/undef. if (isa(C)) @@ -1169,6 +1179,32 @@ } void SCCPInstVisitor::visitCallBase(CallBase &CB) { + auto *CFP = dyn_cast(&CB); + if (CFP) { + switch ((Intrinsic::ID)CFP->getIntrinsicID()) { + case Intrinsic::experimental_constrained_fadd: + case Intrinsic::experimental_constrained_fsub: + case Intrinsic::experimental_constrained_fmul: + case Intrinsic::experimental_constrained_fdiv: + case Intrinsic::experimental_constrained_frem: + // FIXME: return (void) visitBinaryOperator(CB); + break; + case Intrinsic::experimental_constrained_fptosi: + case Intrinsic::experimental_constrained_sitofp: + case Intrinsic::experimental_constrained_fptoui: + case Intrinsic::experimental_constrained_uitofp: + // FIXME: return (void) visitCastInst(CB); + break; + case Intrinsic::experimental_constrained_fcmp: + case Intrinsic::experimental_constrained_fcmps: + return (void) visitCmpInst(CB); + break; + default: + // We only examine the constrained intrinsics that replace + // llvm instructions. + break; + } + } handleCallResult(CB); handleCallArguments(CB); } Index: llvm/test/Transforms/SCCP/strictfp-phis-fcmp.ll =================================================================== --- llvm/test/Transforms/SCCP/strictfp-phis-fcmp.ll +++ llvm/test/Transforms/SCCP/strictfp-phis-fcmp.ll @@ -8,8 +8,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 true ; entry: @@ -32,8 +31,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.maytrap") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 true ; entry: @@ -56,8 +54,8 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.strict") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]] +; CHECK-NEXT: ret i1 true ; entry: @@ -224,8 +222,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.ignore") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: @@ -250,8 +247,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.maytrap") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: @@ -278,7 +274,7 @@ ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.strict") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: Index: llvm/test/Transforms/SCCP/strictfp-phis-fcmps.ll =================================================================== --- llvm/test/Transforms/SCCP/strictfp-phis-fcmps.ll +++ llvm/test/Transforms/SCCP/strictfp-phis-fcmps.ll @@ -8,8 +8,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 true ; entry: @@ -32,8 +31,7 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.maytrap") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 true ; entry: @@ -56,8 +54,8 @@ ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.strict") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"ueq", metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]] +; CHECK-NEXT: ret i1 true ; entry: @@ -223,9 +221,10 @@ ; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]] ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] +; CHECK: dead: +; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.ignore") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: @@ -249,9 +248,10 @@ ; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]] ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] +; CHECK: dead: +; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.maytrap") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: @@ -276,9 +276,11 @@ ; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_TRUE:%.*]], label [[END:%.*]] ; CHECK: if.true: ; CHECK-NEXT: br label [[END]] +; CHECK: dead: +; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[C:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f32(float 1.000000e+00, float 1.000000e+00, metadata !"une", metadata !"fpexcept.strict") #[[ATTR0]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: ret i1 false ; entry: