return DAG.getNode(ISD::OR, DL, VT, Sra, N2);
}
+ // If the comparison is testing for a positive value, we have to invert
+ // the sign bit mask, so only do that transform if the target has a bitwise
+ // 'and not' instruction (the invert is free).
+ // (Cond0 s> -1) ? N1 : 0 --> ~(Cond0 s>> BW-1) & N1
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (CC == ISD::SETGT && isAllOnesOrAllOnesSplat(Cond1) &&
+ isNullOrNullSplat(N2) && TLI.hasAndNot(N2)) {
+ SDLoc DL(N);
+ SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
+ SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
+ SDValue Not = DAG.getNOT(DL, Sra, VT);
+ return DAG.getNode(ISD::AND, DL, VT, Not, N1);
+ }
+ // (X > 0) ? X : 0 <-- This is canonical signed max.
+// if (!(isAllOnesConstant(N1) || (isNullConstant(N1) && N0 == N2)))
+// return SDValue();
+
return SDValue();
}
%r = call <3 x i8> @llvm.umax.v3i8(<3 x i8> %a, <3 x i8> <i8 13, i8 130, i8 130>)
ret <3 x i8> %r
}
+
+define <3 x i8> @umax_sub_vec(<3 x i8> %x, <3 x i8> %y) {
+; CHECK-LABEL: @umax_sub_vec(
+; CHECK-NEXT: [[U:%.*]] = call <3 x i8> @llvm.umax.v3i8(<3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]])
+; CHECK-NEXT: [[R:%.*]] = sub <3 x i8> [[U]], [[Y]]
+; CHECK-NEXT: ret <3 x i8> [[R]]
+;
+ %u = call <3 x i8> @llvm.umax.v3i8(<3 x i8> %x, <3 x i8> %y)
+ %r = sub <3 x i8> %u, %y
+ ret <3 x i8> %r
+}
+
+define i8 @umax_sub_use(i8 %x, i8 %y) {
+; CHECK-LABEL: @umax_sub_use(
+; CHECK-NEXT: [[U:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
+; CHECK-NEXT: call void @use(i8 [[U]])
+; CHECK-NEXT: [[R:%.*]] = sub i8 [[U]], [[Y]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %u = call i8 @llvm.umax.i8(i8 %x, i8 %y)
+ call void @use(i8 %u)
+ %r = sub i8 %u, %y
+ ret i8 %r
+}