diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index e38cafdf55c46..a52d0eddee92a 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -1571,6 +1571,14 @@ def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8), def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm), (tCMPr tGPR:$Rn, tGPR:$Rm)>; +// -(n & 1) -> (n << 31) >> 31 to avoid materializing constants on Thumb1 +def : T1Pat<(ineg (and tGPR:$Rn, (i32 1))), + (tASRri (tLSLri tGPR:$Rn, 31), 31)>, + Requires<[IsThumb, IsThumb1Only]>; +def : T1Pat<(sub (i32 0), (and tGPR:$Rn, (i32 1))), + (tASRri (tLSLri tGPR:$Rn, 31), 31)>, + Requires<[IsThumb, IsThumb1Only]>; + // Bswap 16 with load/store def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)), (tREV16 (tLDRHi t_addrmode_is2:$addr))>; diff --git a/llvm/test/CodeGen/ARM/select_const.ll b/llvm/test/CodeGen/ARM/select_const.ll index 180daa12e7c52..54a14e7ac7343 100644 --- a/llvm/test/CodeGen/ARM/select_const.ll +++ b/llvm/test/CodeGen/ARM/select_const.ll @@ -276,9 +276,8 @@ define i32 @select_neg1_or_0(i1 %cond) { ; ; THUMB-LABEL: select_neg1_or_0: ; THUMB: @ %bb.0: -; THUMB-NEXT: movs r1, #1 -; THUMB-NEXT: ands r1, r0 -; THUMB-NEXT: rsbs r0, r1, #0 +; THUMB-NEXT: lsls r0, r0, #31 +; THUMB-NEXT: asrs r0, r0, #31 ; THUMB-NEXT: bx lr %sel = select i1 %cond, i32 -1, i32 0 ret i32 %sel diff --git a/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll b/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll index 00eed6483cc12..65f2af078232c 100644 --- a/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll +++ b/llvm/test/CodeGen/Thumb/srem-seteq-illegal-types.ll @@ -81,15 +81,14 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind { ; CHECK-NEXT: push {r4, r5, r6, r7, lr} ; CHECK-NEXT: .pad #12 ; CHECK-NEXT: sub sp, #12 -; CHECK-NEXT: movs r7, r3 -; CHECK-NEXT: str r2, [sp, #4] @ 4-byte Spill -; CHECK-NEXT: movs r5, #1 -; CHECK-NEXT: ands r1, r5 -; CHECK-NEXT: rsbs r1, r1, #0 +; CHECK-NEXT: str r3, [sp, #4] @ 4-byte Spill +; CHECK-NEXT: movs r5, r2 +; CHECK-NEXT: lsls r1, r1, #31 +; CHECK-NEXT: asrs r1, r1, #31 ; CHECK-NEXT: movs r6, #9 -; CHECK-NEXT: movs r3, #0 -; CHECK-NEXT: str r3, [sp] @ 4-byte Spill +; CHECK-NEXT: movs r7, #0 ; CHECK-NEXT: movs r2, r6 +; CHECK-NEXT: movs r3, r7 ; CHECK-NEXT: bl __aeabi_ldivmod ; CHECK-NEXT: movs r4, r2 ; CHECK-NEXT: movs r0, #3 @@ -98,13 +97,14 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind { ; CHECK-NEXT: orrs r4, r3 ; CHECK-NEXT: subs r0, r4, #1 ; CHECK-NEXT: sbcs r4, r0 -; CHECK-NEXT: ands r7, r5 -; CHECK-NEXT: rsbs r1, r7, #0 ; CHECK-NEXT: ldr r0, [sp, #4] @ 4-byte Reload +; CHECK-NEXT: lsls r0, r0, #31 +; CHECK-NEXT: asrs r1, r0, #31 +; CHECK-NEXT: movs r0, r5 ; CHECK-NEXT: movs r2, r6 -; CHECK-NEXT: ldr r7, [sp] @ 4-byte Reload ; CHECK-NEXT: movs r3, r7 ; CHECK-NEXT: bl __aeabi_ldivmod +; CHECK-NEXT: movs r5, #1 ; CHECK-NEXT: movs r0, r5 ; CHECK-NEXT: bics r0, r3 ; CHECK-NEXT: movs r1, #2 @@ -113,12 +113,12 @@ define <3 x i1> @test_srem_vec(<3 x i33> %X) nounwind { ; CHECK-NEXT: orrs r6, r0 ; CHECK-NEXT: subs r0, r6, #1 ; CHECK-NEXT: sbcs r6, r0 -; CHECK-NEXT: ldr r0, [sp, #36] -; CHECK-NEXT: ands r0, r5 -; CHECK-NEXT: rsbs r1, r0, #0 ; CHECK-NEXT: movs r0, #8 ; CHECK-NEXT: mvns r2, r0 ; CHECK-NEXT: mvns r3, r7 +; CHECK-NEXT: ldr r0, [sp, #36] +; CHECK-NEXT: lsls r0, r0, #31 +; CHECK-NEXT: asrs r1, r0, #31 ; CHECK-NEXT: ldr r0, [sp, #32] ; CHECK-NEXT: bl __aeabi_ldivmod ; CHECK-NEXT: ands r5, r3