}
if (auto *Sel = dyn_cast<SelectInst>(Src)) {
- // We are casting a select. Try to fold the cast into the select, but only
- // if the select does not have a compare instruction with matching operand
- // types. Creating a select with operands that are different sizes than its
+ // We are casting a select. Try to fold the cast into the select if the
+ // select does not have a compare instruction with matching operand types
+ // or the select is likely better done in a narrow type.
+ // Creating a select with operands that are different sizes than its
// condition may inhibit other folds and lead to worse codegen.
auto *Cmp = dyn_cast<CmpInst>(Sel->getCondition());
- if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType())
+ if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType() ||
+ (CI.getOpcode() == Instruction::Trunc &&
+ shouldChangeType(CI.getSrcTy(), CI.getType()))) {
if (Instruction *NV = FoldOpIntoSelect(CI, Sel)) {
replaceAllDbgUsesWith(*Sel, *NV, CI, DT);
return NV;
}
+ }
}
// If we are casting a PHI, then fold the cast into the PHI.
define i16 @trunc(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @trunc(
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[Z:%.*]]
-; CHECK-NEXT: [[R:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[Z:%.*]] to i16
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i16 42, i16 [[TMP1]]
; CHECK-NEXT: ret i16 [[R]]
;
%cmp = icmp ult i32 %x, %y
; CHECK-LABEL: @thisdoesnotloop(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[L1:%.*]] = icmp slt i32 [[A:%.*]], -128
-; CHECK-NEXT: [[L2:%.*]] = select i1 [[L1]], i32 -128, i32 [[B:%.*]]
-; CHECK-NEXT: [[CONV7:%.*]] = trunc i32 [[L2]] to i8
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[B:%.*]] to i8
+; CHECK-NEXT: [[CONV7:%.*]] = select i1 [[L1]], i8 -128, i8 [[TMP0]]
; CHECK-NEXT: ret i8 [[CONV7]]
;
entry:
ret <2 x i8> %tr
}
-; FIXME: If the select is narrowed based on the target's datalayout, we allow more optimizations.
+; If the select is narrowed based on the target's datalayout, we allow more optimizations.
define i16 @PR44545(i32 %t0, i32 %data) {
; CHECK-LABEL: @PR44545(
-; CHECK-NEXT: [[T1:%.*]] = add nuw nsw i32 [[T0:%.*]], 1
; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq i32 [[DATA:%.*]], 0
-; CHECK-NEXT: [[FFS:%.*]] = select i1 [[ISZERO]], i32 0, i32 [[T1]]
-; CHECK-NEXT: [[CAST:%.*]] = trunc i32 [[FFS]] to i16
-; CHECK-NEXT: [[SUB:%.*]] = add nsw i16 [[CAST]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[T0:%.*]] to i16
+; CHECK-NEXT: [[SUB:%.*]] = select i1 [[ISZERO]], i16 -1, i16 [[TMP1]]
; CHECK-NEXT: ret i16 [[SUB]]
;
%t1 = add nuw nsw i32 %t0, 1