This is from D49238 code review comments.
Currently opt can fold scalar type for instruction pattern:
define i32 @Op1Negated_Scalar(i32 %x) { %sub = sub nsw i32 0, %x %cmp = icmp sgt i32 %sub, -1 %cond = select i1 %cmp, i32 %sub, i32 %x ret i32 %cond }
to
define i32 @Op1Negated_Scalar(i32 %x) { %sub = sub nsw i32 0, %x %cmp = icmp slt i32 %x, 0 %cond = select i1 %cmp, i32 %sub, i32 %x ret i32 %cond }
But it can not fold vector type for the same instruction pattern:
define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) { %sub = sub nsw <2 x i32> zeroinitializer, %x %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x ret <2 x i32> %cond }
We should also fold %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1> to %cmp = icmp slt <2 x i32> %x, zeroinitializer as what we do for scalar type.
Note: there must be two uses of %sub in case Op1Negated_Vec(), %cmp and %cond, otherwise if only one use %cmp, icmp is folded in earlier function in visitICmpInst() -> foldICmpWithConstant() -> foldICmpSubConstant().