diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 3fea1910ffe..c3be1197d3c 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -693,6 +693,18 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, if (isa(V2)) return V1; if (isa(Cond)) return V1; if (V1 == V2) return V1; + + if (ConstantExpr *TrueVal = dyn_cast(V1)) { + if (TrueVal->getOpcode() == Instruction::Select) + if (TrueVal->getOperand(0) == Cond) + return ConstantExpr::getSelect(Cond, TrueVal->getOperand(1), V2); + } + if (ConstantExpr *FalseVal = dyn_cast(V2)) { + if (FalseVal->getOpcode() == Instruction::Select) + if (FalseVal->getOperand(0) == Cond) + return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2)); + } + return 0; } diff --git a/test/Transforms/ConstProp/constant-expr.ll b/test/Transforms/ConstProp/constant-expr.ll index 33ed1a53c3e..1088fa6959a 100644 --- a/test/Transforms/ConstProp/constant-expr.ll +++ b/test/Transforms/ConstProp/constant-expr.ll @@ -100,3 +100,12 @@ ; CHECK: pr9011_14 = constant i128 0 @pr9011_15 = constant i128 bitcast (<4 x i32> zeroinitializer to i128) ; CHECK: pr9011_15 = constant i128 0 + +@select = internal constant + i32 select (i1 icmp ult (i32 ptrtoint (i8* @X to i32), + i32 ptrtoint (i8* @Y to i32)), + i32 select (i1 icmp ult (i32 ptrtoint (i8* @X to i32), + i32 ptrtoint (i8* @Y to i32)), + i32 10, i32 20), + i32 30) +; CHECK: select = internal constant i32 select {{.*}} i32 10, i32 30