Loading llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -56,6 +56,10 @@ static void getRelevantOperands(Instruction *I, SmallVectorImpl<Value *> &Ops) { Ops.push_back(I->getOperand(0)); Ops.push_back(I->getOperand(1)); break; case Instruction::Select: Ops.push_back(I->getOperand(1)); Ops.push_back(I->getOperand(2)); break; default: llvm_unreachable("Unreachable!"); } Loading Loading @@ -114,7 +118,8 @@ bool TruncInstCombine::buildTruncExpressionDag() { case Instruction::Mul: case Instruction::And: case Instruction::Or: case Instruction::Xor: { case Instruction::Xor: case Instruction::Select: { SmallVector<Value *, 2> Operands; getRelevantOperands(I, Operands); for (Value *Operand : Operands) Loading @@ -123,7 +128,7 @@ bool TruncInstCombine::buildTruncExpressionDag() { } default: // TODO: Can handle more cases here: // 1. select, shufflevector, extractelement, insertelement // 1. shufflevector, extractelement, insertelement // 2. udiv, urem // 3. shl, lshr, ashr // 4. phi node(and loop handling) Loading Loading @@ -351,6 +356,13 @@ void TruncInstCombine::ReduceExpressionDag(Type *SclTy) { Res = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS); break; } case Instruction::Select: { Value *Op0 = I->getOperand(0); Value *LHS = getReducedOperand(I->getOperand(1), SclTy); Value *RHS = getReducedOperand(I->getOperand(2), SclTy); Res = Builder.CreateSelect(Op0, LHS, RHS); break; } default: llvm_unreachable("Unhandled instruction"); } Loading llvm/test/Transforms/AggressiveInstCombine/trunc_select.ll +24 −41 Original line number Diff line number Diff line Loading @@ -7,11 +7,8 @@ target datalayout = "e-m:m-p1:64:64:64-p:32:32:32-n8:16:32" define dso_local i16 @select_i16(i16 %a, i16 %b, i1 %cond) { ; CHECK-LABEL: @select_i16( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[A:%.*]], i16 [[B:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv0 = sext i16 %a to i32 Loading @@ -24,11 +21,8 @@ entry: define dso_local i8 @select_i8(i8 %a, i8 %b, i1 %cond) { ; CHECK-LABEL: @select_i8( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv0 = sext i8 %a to i32 Loading @@ -41,11 +35,10 @@ entry: define dso_local i16 @select_i8Ops_trunc_i16(i8 %a, i8 %b, i1 %cond) { ; CHECK-LABEL: @select_i8Ops_trunc_i16( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i16 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[CONV0]], i16 [[CONV1]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv0 = sext i8 %a to i32 Loading @@ -59,10 +52,8 @@ entry: define dso_local i16 @select_i16_const(i16 %a, i1 %cond) { ; CHECK-LABEL: @select_i16_const( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 109, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 109, i16 [[A:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i16 %a to i32 Loading @@ -75,10 +66,8 @@ entry: define dso_local i16 @select_i16_bigConst(i16 %a, i1 %cond) { ; CHECK-LABEL: @select_i16_bigConst( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 3080196, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 4, i16 [[A:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i16 %a to i32 Loading @@ -90,10 +79,8 @@ entry: define dso_local i8 @select_i8_const(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_i8_const( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 109, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 109, i8 [[A:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -106,10 +93,8 @@ entry: define dso_local i8 @select_i8_bigConst(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_i8_bigConst( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 20228, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 4, i8 [[A:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -121,11 +106,10 @@ entry: define dso_local i16 @select_sext(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_sext( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[SUB]], i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[SUB:%.*]] = sub i16 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[SUB]], i16 [[CONV]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -138,11 +122,10 @@ entry: define dso_local i16 @select_zext(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_zext( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[SUB]], i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[SUB:%.*]] = sub i16 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[SUB]], i16 [[CONV]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = zext i8 %a to i32 Loading Loading
llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -56,6 +56,10 @@ static void getRelevantOperands(Instruction *I, SmallVectorImpl<Value *> &Ops) { Ops.push_back(I->getOperand(0)); Ops.push_back(I->getOperand(1)); break; case Instruction::Select: Ops.push_back(I->getOperand(1)); Ops.push_back(I->getOperand(2)); break; default: llvm_unreachable("Unreachable!"); } Loading Loading @@ -114,7 +118,8 @@ bool TruncInstCombine::buildTruncExpressionDag() { case Instruction::Mul: case Instruction::And: case Instruction::Or: case Instruction::Xor: { case Instruction::Xor: case Instruction::Select: { SmallVector<Value *, 2> Operands; getRelevantOperands(I, Operands); for (Value *Operand : Operands) Loading @@ -123,7 +128,7 @@ bool TruncInstCombine::buildTruncExpressionDag() { } default: // TODO: Can handle more cases here: // 1. select, shufflevector, extractelement, insertelement // 1. shufflevector, extractelement, insertelement // 2. udiv, urem // 3. shl, lshr, ashr // 4. phi node(and loop handling) Loading Loading @@ -351,6 +356,13 @@ void TruncInstCombine::ReduceExpressionDag(Type *SclTy) { Res = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS); break; } case Instruction::Select: { Value *Op0 = I->getOperand(0); Value *LHS = getReducedOperand(I->getOperand(1), SclTy); Value *RHS = getReducedOperand(I->getOperand(2), SclTy); Res = Builder.CreateSelect(Op0, LHS, RHS); break; } default: llvm_unreachable("Unhandled instruction"); } Loading
llvm/test/Transforms/AggressiveInstCombine/trunc_select.ll +24 −41 Original line number Diff line number Diff line Loading @@ -7,11 +7,8 @@ target datalayout = "e-m:m-p1:64:64:64-p:32:32:32-n8:16:32" define dso_local i16 @select_i16(i16 %a, i16 %b, i1 %cond) { ; CHECK-LABEL: @select_i16( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[A:%.*]], i16 [[B:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv0 = sext i16 %a to i32 Loading @@ -24,11 +21,8 @@ entry: define dso_local i8 @select_i8(i8 %a, i8 %b, i1 %cond) { ; CHECK-LABEL: @select_i8( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv0 = sext i8 %a to i32 Loading @@ -41,11 +35,10 @@ entry: define dso_local i16 @select_i8Ops_trunc_i16(i8 %a, i8 %b, i1 %cond) { ; CHECK-LABEL: @select_i8Ops_trunc_i16( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[CONV0]], i32 [[CONV1]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV0:%.*]] = sext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i16 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[CONV0]], i16 [[CONV1]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv0 = sext i8 %a to i32 Loading @@ -59,10 +52,8 @@ entry: define dso_local i16 @select_i16_const(i16 %a, i1 %cond) { ; CHECK-LABEL: @select_i16_const( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 109, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 109, i16 [[A:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i16 %a to i32 Loading @@ -75,10 +66,8 @@ entry: define dso_local i16 @select_i16_bigConst(i16 %a, i1 %cond) { ; CHECK-LABEL: @select_i16_bigConst( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 3080196, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 4, i16 [[A:%.*]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i16 %a to i32 Loading @@ -90,10 +79,8 @@ entry: define dso_local i8 @select_i8_const(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_i8_const( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 109, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 109, i8 [[A:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -106,10 +93,8 @@ entry: define dso_local i8 @select_i8_bigConst(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_i8_bigConst( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 20228, i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i8 ; CHECK-NEXT: ret i8 [[CONV4]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i8 4, i8 [[A:%.*]] ; CHECK-NEXT: ret i8 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -121,11 +106,10 @@ entry: define dso_local i16 @select_sext(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_sext( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[SUB]], i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[SUB:%.*]] = sub i16 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[SUB]], i16 [[CONV]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = sext i8 %a to i32 Loading @@ -138,11 +122,10 @@ entry: define dso_local i16 @select_zext(i8 %a, i1 %cond) { ; CHECK-LABEL: @select_zext( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[SUB]], i32 [[CONV]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i32 [[SEL]] to i16 ; CHECK-NEXT: ret i16 [[CONV4]] ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i16 ; CHECK-NEXT: [[SUB:%.*]] = sub i16 0, [[CONV]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i16 [[SUB]], i16 [[CONV]] ; CHECK-NEXT: ret i16 [[SEL]] ; entry: %conv = zext i8 %a to i32 Loading