diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -167,9 +167,9 @@ [SDNPInGlue]>; def ARMsubs : SDNode<"ARMISD::SUBS", SDTIntBinOp, [SDNPOutGlue]>; -def ARMssatnoshift : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>; +def ARMssat : SDNode<"ARMISD::SSAT", SDTIntSatNoShOp, []>; -def ARMusatnoshift : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>; +def ARMusat : SDNode<"ARMISD::USAT", SDTIntSatNoShOp, []>; def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; @@ -4082,9 +4082,9 @@ (SSAT imm1_32:$pos, GPRnopc:$a, 0)>; def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm0_31:$pos), (USAT imm0_31:$pos, GPRnopc:$a, 0)>; -def : ARMPat<(ARMssatnoshift GPRnopc:$Rn, imm0_31:$imm), +def : ARMPat<(ARMssat GPRnopc:$Rn, imm0_31:$imm), (SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>; -def : ARMPat<(ARMusatnoshift GPRnopc:$Rn, imm0_31:$imm), +def : ARMPat<(ARMusat GPRnopc:$Rn, imm0_31:$imm), (USAT imm0_31:$imm, GPRnopc:$Rn, 0)>; def : ARMV6Pat<(int_arm_ssat16 GPRnopc:$a, imm1_16:$pos), (SSAT16 imm1_16:$pos, GPRnopc:$a)>; @@ -4098,6 +4098,14 @@ (USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; def : ARMV6Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos), (USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>; +def : ARMPat<(ARMssat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), + (SSAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; +def : ARMPat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), + (SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; +def : ARMPat<(ARMusat (shl GPRnopc:$Rn, imm0_31:$shft), imm0_31:$pos), + (USAT imm0_31:$pos, GPRnopc:$Rn, imm0_31:$shft)>; +def : ARMPat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), + (USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -2624,9 +2624,9 @@ let Inst{4} = 0; } -def : T2Pat<(ARMssatnoshift GPRnopc:$Rn, imm0_31:$imm), +def : T2Pat<(ARMssat GPRnopc:$Rn, imm0_31:$imm), (t2SSAT imm0_31:$imm, GPRnopc:$Rn, 0)>; -def : T2Pat<(ARMusatnoshift GPRnopc:$Rn, imm0_31:$imm), +def : T2Pat<(ARMusat GPRnopc:$Rn, imm0_31:$imm), (t2USAT imm0_31:$imm, GPRnopc:$Rn, 0)>; def : T2Pat<(int_arm_ssat GPR:$a, imm1_32:$pos), (t2SSAT imm1_32:$pos, GPR:$a, 0)>; @@ -2644,6 +2644,14 @@ (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; def : T2Pat<(int_arm_usat (sra GPRnopc:$a, asr_imm:$shft), imm0_31:$pos), (t2USAT imm0_31:$pos, GPRnopc:$a, asr_imm:$shft)>; +def : T2Pat<(ARMssat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos), + (t2SSAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; +def : T2Pat<(ARMssat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), + (t2SSAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; +def : T2Pat<(ARMusat (shl GPRnopc:$a, imm0_31:$shft), imm0_31:$pos), + (t2USAT imm0_31:$pos, GPRnopc:$a, imm0_31:$shft)>; +def : T2Pat<(ARMusat (sra GPRnopc:$Rn, asr_imm:$shft), imm0_31:$pos), + (t2USAT imm0_31:$pos, GPRnopc:$Rn, asr_imm:$shft)>; //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/ARM/ssat-with-shift.ll b/llvm/test/CodeGen/ARM/ssat-with-shift.ll --- a/llvm/test/CodeGen/ARM/ssat-with-shift.ll +++ b/llvm/test/CodeGen/ARM/ssat-with-shift.ll @@ -24,4 +24,32 @@ ret i32 %0 } +define arm_aapcs_vfpcc i32 @ssat_lsl2(i32 %num){ +; CHECK-LABEL: ssat_lsl2: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: ssat r0, #16, r0, lsl #15 +; CHECK-NEXT: bx lr +entry: + %shl = shl nsw i32 %num, 15 + %0 = icmp sgt i32 %shl, -32768 + %1 = select i1 %0, i32 %shl, i32 -32768 + %2 = icmp slt i32 %1, 32767 + %3 = select i1 %2, i32 %1, i32 32767 + ret i32 %3 +} + +define arm_aapcs_vfpcc i32 @ssat_asr2(i32 %num){ +; CHECK-LABEL: ssat_asr2: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: ssat r0, #16, r0, asr #15 +; CHECK-NEXT: bx lr +entry: + %shr = ashr i32 %num, 15 + %0 = icmp sgt i32 %shr, -32768 + %1 = select i1 %0, i32 %shr, i32 -32768 + %2 = icmp slt i32 %1, 32767 + %3 = select i1 %2, i32 %1, i32 32767 + ret i32 %3 +} + declare i32 @llvm.arm.ssat(i32, i32) diff --git a/llvm/test/CodeGen/ARM/usat-with-shift.ll b/llvm/test/CodeGen/ARM/usat-with-shift.ll --- a/llvm/test/CodeGen/ARM/usat-with-shift.ll +++ b/llvm/test/CodeGen/ARM/usat-with-shift.ll @@ -24,4 +24,32 @@ ret i32 %0 } +define arm_aapcs_vfpcc i32 @usat_lsl2(i32 %num){ +; CHECK-LABEL: usat_lsl2: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: usat r0, #15, r0, lsl #15 +; CHECK-NEXT: bx lr +entry: + %shl = shl nsw i32 %num, 15 + %0 = icmp sgt i32 %shl, 0 + %1 = select i1 %0, i32 %shl, i32 0 + %2 = icmp slt i32 %1, 32767 + %3 = select i1 %2, i32 %1, i32 32767 + ret i32 %3 +} + +define arm_aapcs_vfpcc i32 @usat_asr2(i32 %num){ +; CHECK-LABEL: usat_asr2: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: usat r0, #15, r0, asr #15 +; CHECK-NEXT: bx lr +entry: + %shr = ashr i32 %num, 15 + %0 = icmp sgt i32 %shr, 0 + %1 = select i1 %0, i32 %shr, i32 0 + %2 = icmp slt i32 %1, 32767 + %3 = select i1 %2, i32 %1, i32 32767 + ret i32 %3 +} + declare i32 @llvm.arm.usat(i32, i32) diff --git a/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll b/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll --- a/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll +++ b/llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll @@ -1145,8 +1145,7 @@ ; CHECK-NEXT: ldrsh r0, [r12], #2 ; CHECK-NEXT: ldrsh r1, [r6], #2 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #15 -; CHECK-NEXT: ssat r0, #16, r0 +; CHECK-NEXT: ssat r0, #16, r0, asr #15 ; CHECK-NEXT: strh r0, [r4], #2 ; CHECK-NEXT: le lr, .LBB5_7 ; CHECK-NEXT: .LBB5_8: @ %for.cond.cleanup @@ -1279,8 +1278,7 @@ ; CHECK-NEXT: ldrsh r0, [r12], #2 ; CHECK-NEXT: ldrsh r1, [r6], #2 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #15 -; CHECK-NEXT: ssat r0, #16, r0 +; CHECK-NEXT: ssat r0, #16, r0, asr #15 ; CHECK-NEXT: strh r0, [r4], #2 ; CHECK-NEXT: le lr, .LBB6_7 ; CHECK-NEXT: .LBB6_8: @ %for.cond.cleanup @@ -1410,8 +1408,7 @@ ; CHECK-NEXT: ldrsh r0, [r12], #2 ; CHECK-NEXT: ldrsh r1, [r6], #2 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #15 -; CHECK-NEXT: ssat r0, #16, r0 +; CHECK-NEXT: ssat r0, #16, r0, asr #15 ; CHECK-NEXT: strh r0, [r4], #2 ; CHECK-NEXT: le lr, .LBB7_7 ; CHECK-NEXT: .LBB7_8: @ %for.cond.cleanup @@ -2218,8 +2215,7 @@ ; CHECK-NEXT: ldrsb r0, [r12], #1 ; CHECK-NEXT: ldrsb r1, [r6], #1 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #7 -; CHECK-NEXT: ssat r0, #8, r0 +; CHECK-NEXT: ssat r0, #8, r0, asr #7 ; CHECK-NEXT: strb r0, [r4], #1 ; CHECK-NEXT: le lr, .LBB13_7 ; CHECK-NEXT: .LBB13_8: @ %for.cond.cleanup @@ -2346,8 +2342,7 @@ ; CHECK-NEXT: ldrsb r0, [r12], #1 ; CHECK-NEXT: ldrsb r1, [r6], #1 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #7 -; CHECK-NEXT: ssat r0, #8, r0 +; CHECK-NEXT: ssat r0, #8, r0, asr #7 ; CHECK-NEXT: strb r0, [r4], #1 ; CHECK-NEXT: le lr, .LBB14_7 ; CHECK-NEXT: .LBB14_8: @ %for.cond.cleanup @@ -2480,8 +2475,7 @@ ; CHECK-NEXT: ldrsb r0, [r12], #1 ; CHECK-NEXT: ldrsb r1, [r6], #1 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #7 -; CHECK-NEXT: ssat r0, #8, r0 +; CHECK-NEXT: ssat r0, #8, r0, asr #7 ; CHECK-NEXT: strb r0, [r4], #1 ; CHECK-NEXT: le lr, .LBB15_7 ; CHECK-NEXT: .LBB15_8: @ %for.cond.cleanup @@ -2611,8 +2605,7 @@ ; CHECK-NEXT: ldrsb r0, [r12], #1 ; CHECK-NEXT: ldrsb r1, [r6], #1 ; CHECK-NEXT: muls r0, r1, r0 -; CHECK-NEXT: asrs r0, r0, #7 -; CHECK-NEXT: ssat r0, #8, r0 +; CHECK-NEXT: ssat r0, #8, r0, asr #7 ; CHECK-NEXT: strb r0, [r4], #1 ; CHECK-NEXT: le lr, .LBB16_7 ; CHECK-NEXT: .LBB16_8: @ %for.cond.cleanup