Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -202,7 +202,7 @@ if (!VT.isFloatingPoint() && VT != MVT::v2i64 && VT != MVT::v1i64) - for (unsigned Opcode : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}) + for (auto Opcode : {ISD::ABS, ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}) setOperationAction(Opcode, VT, Legal); } @@ -3316,6 +3316,9 @@ } return Result; } + case Intrinsic::arm_neon_vabs: + return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(), + Op.getOperand(1)); case Intrinsic::arm_neon_vmulls: case Intrinsic::arm_neon_vmullu: { unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls) Index: lib/Target/ARM/ARMInstrNEON.td =================================================================== --- lib/Target/ARM/ARMInstrNEON.td +++ lib/Target/ARM/ARMInstrNEON.td @@ -5558,8 +5558,7 @@ // VABS : Vector Absolute Value defm VABS : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0, - IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", - int_arm_neon_vabs>; + IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", abs>; def VABSfd : N2VD<0b11, 0b11, 0b10, 0b01, 0b01110, 0, "vabs", "f32", v2f32, v2f32, fabs>; @@ -5575,29 +5574,6 @@ v8f16, v8f16, fabs>, Requires<[HasNEON, HasFullFP16]>; -def : Pat<(xor (v2i32 (bitconvert (v8i8 (NEONvshrs DPR:$src, (i32 7))))), - (v2i32 (bitconvert (v8i8 (add DPR:$src, - (NEONvshrs DPR:$src, (i32 7))))))), - (VABSv8i8 DPR:$src)>; -def : Pat<(xor (v2i32 (bitconvert (v4i16 (NEONvshrs DPR:$src, (i32 15))))), - (v2i32 (bitconvert (v4i16 (add DPR:$src, - (NEONvshrs DPR:$src, (i32 15))))))), - (VABSv4i16 DPR:$src)>; -def : Pat<(xor (v2i32 (NEONvshrs DPR:$src, (i32 31))), - (v2i32 (add DPR:$src, (NEONvshrs DPR:$src, (i32 31))))), - (VABSv2i32 DPR:$src)>; -def : Pat<(xor (v4i32 (bitconvert (v16i8 (NEONvshrs QPR:$src, (i32 7))))), - (v4i32 (bitconvert (v16i8 (add QPR:$src, - (NEONvshrs QPR:$src, (i32 7))))))), - (VABSv16i8 QPR:$src)>; -def : Pat<(xor (v4i32 (bitconvert (v8i16 (NEONvshrs QPR:$src, (i32 15))))), - (v4i32 (bitconvert (v8i16 (add QPR:$src, - (NEONvshrs QPR:$src, (i32 15))))))), - (VABSv8i16 QPR:$src)>; -def : Pat<(xor (v4i32 (NEONvshrs QPR:$src, (i32 31))), - (v4i32 (add QPR:$src, (NEONvshrs QPR:$src, (i32 31))))), - (VABSv4i32 QPR:$src)>; - // VQABS : Vector Saturating Absolute Value defm VQABS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0, IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s", Index: test/CodeGen/ARM/vabs.ll =================================================================== --- test/CodeGen/ARM/vabs.ll +++ test/CodeGen/ARM/vabs.ll @@ -8,6 +8,22 @@ ret <8 x i8> %tmp2 } +define <8 x i8> @vabss8_fold(<8 x i8>* %A) nounwind { +; CHECK-LABEL: vabss8_fold: +; CHECK: vldr d16, .LCPI1_0 +; CHECK: .LCPI1_0: +; CHECK-NEXT: .byte 128 @ 0x80 +; CHECK-NEXT: .byte 127 @ 0x7f +; CHECK-NEXT: .byte 1 @ 0x1 +; CHECK-NEXT: .byte 0 @ 0x0 +; CHECK-NEXT: .byte 1 @ 0x1 +; CHECK-NEXT: .byte 127 @ 0x7f +; CHECK-NEXT: .byte 128 @ 0x80 +; CHECK-NEXT: .byte 1 @ 0x1 + %tmp1 = call <8 x i8> @llvm.arm.neon.vabs.v8i8(<8 x i8> ) + ret <8 x i8> %tmp1 +} + define <4 x i16> @vabss16(<4 x i16>* %A) nounwind { ;CHECK-LABEL: vabss16: ;CHECK: vabs.s16 @@ -16,6 +32,18 @@ ret <4 x i16> %tmp2 } +define <4 x i16> @vabss16_fold() nounwind { +; CHECK-LABEL: vabss16_fold: +; CHECK: vldr d16, .LCPI3_0 +; CHECK: .LCPI3_0: +; CHECK-NEXT: .short 32768 @ 0x8000 +; CHECK-NEXT: .short 32767 @ 0x7fff +; CHECK-NEXT: .short 255 @ 0xff +; CHECK-NEXT: .short 32768 @ 0x8000 + %tmp1 = call <4 x i16> @llvm.arm.neon.vabs.v4i16(<4 x i16> ) + ret <4 x i16> %tmp1 +} + define <2 x i32> @vabss32(<2 x i32>* %A) nounwind { ;CHECK-LABEL: vabss32: ;CHECK: vabs.s32 @@ -24,6 +52,16 @@ ret <2 x i32> %tmp2 } +define <2 x i32> @vabss32_fold() nounwind { +; CHECK-LABEL: vabss32_fold: +; CHECK: vldr d16, .LCPI5_0 +; CHECK: .LCPI5_0: +; CHECK-NEXT: .long 2147483647 @ 0x7fffffff +; CHECK-NEXT: .long 2147483648 @ 0x80000000 + %tmp1 = call <2 x i32> @llvm.arm.neon.vabs.v2i32(<2 x i32> ) + ret <2 x i32> %tmp1 +} + define <2 x float> @vabsf32(<2 x float>* %A) nounwind { ;CHECK-LABEL: vabsf32: ;CHECK: vabs.f32