diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -6592,6 +6592,13 @@ } return getBuildVector(VT, DL, Ops); } + + if (N1.getOpcode() == ISD::SPLAT_VECTOR && + isa(N1.getOperand(0))) + return getNode( + ISD::SPLAT_VECTOR, DL, VT, + SignExtendInReg(N1.getConstantOperandAPInt(0), + N1.getOperand(0).getValueType())); break; } case ISD::FP_TO_SINT_SAT: diff --git a/llvm/test/CodeGen/AArch64/sve-fp-int-min-max.ll b/llvm/test/CodeGen/AArch64/sve-fp-int-min-max.ll --- a/llvm/test/CodeGen/AArch64/sve-fp-int-min-max.ll +++ b/llvm/test/CodeGen/AArch64/sve-fp-int-min-max.ll @@ -6,21 +6,17 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: mov w8, #3745 // =0xea1 -; CHECK-NEXT: movk w8, #16618, lsl #16 ; CHECK-NEXT: ld1w { z3.d }, p0/z, [x0] +; CHECK-NEXT: movk w8, #16618, lsl #16 ; CHECK-NEXT: mov w9, #57344 // =0xe000 -; CHECK-NEXT: mov z6.d, #1023 // =0x3ff ; CHECK-NEXT: movk w9, #17535, lsl #16 ; CHECK-NEXT: mov z4.s, w8 ; CHECK-NEXT: fmul z4.s, p0/m, z4.s, z3.s ; CHECK-NEXT: mov z5.s, w9 ; CHECK-NEXT: fadd z4.s, p0/m, z4.s, z5.s -; CHECK-NEXT: mov z5.d, #0 // =0x0 +; CHECK-NEXT: mov z5.d, #1023 // =0x3ff ; CHECK-NEXT: fcvtzs z4.d, p0/m, z4.s -; CHECK-NEXT: sxtw z5.d, p0/m, z5.d -; CHECK-NEXT: smax z4.d, p0/m, z4.d, z5.d -; CHECK-NEXT: movprfx z5, z6 -; CHECK-NEXT: sxtw z5.d, p0/m, z6.d +; CHECK-NEXT: smax z4.d, z4.d, #0 ; CHECK-NEXT: smin z4.d, p0/m, z4.d, z5.d ; CHECK-NEXT: cmpne p1.d, p0/z, z4.d, #0 ; CHECK-NEXT: ld1w { z4.d }, p1/z, [x1] diff --git a/llvm/test/CodeGen/AArch64/sve-splat-sext.ll b/llvm/test/CodeGen/AArch64/sve-splat-sext.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-splat-sext.ll @@ -0,0 +1,40 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O2 -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +define @sext_splat_v8i16_128() { +; CHECK-LABEL: sext_splat_v8i16_128: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.h, #-128 // =0xffffffffffffff80 +; CHECK-NEXT: ret + %i = insertelement poison, i16 128, i32 0 + %s = shufflevector %i, poison, zeroinitializer + %a = shl %s, shufflevector ( insertelement( undef, i16 8, i32 0), undef, zeroinitializer) + %b = ashr %a, shufflevector ( insertelement( undef, i16 8, i32 0), undef, zeroinitializer) + ret %b +} + +define @sext_icmp_splat_v8i16_128( %d) { +; CHECK-LABEL: sext_icmp_splat_v8i16_128: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: sxtb z0.h, p0/m, z0.h +; CHECK-NEXT: cmpgt p0.h, p0/z, z0.h, #-1 +; CHECK-NEXT: ret + %i = insertelement poison, i8 128, i32 0 + %s = shufflevector %i, poison, zeroinitializer + %c = icmp ugt %s, %d + ret %c +} + +define @sext_icmp_splat_v4i16_128( %d) { +; CHECK-LABEL: sext_icmp_splat_v4i16_128: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: sxtb z0.s, p0/m, z0.s +; CHECK-NEXT: cmpgt p0.s, p0/z, z0.s, #-1 +; CHECK-NEXT: ret + %i = insertelement poison, i8 128, i32 0 + %s = shufflevector %i, poison, zeroinitializer + %c = icmp ugt %s, %d + ret %c +}