diff --git a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp index 3417c74e359b..caa0e4d80397 100644 --- a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp +++ b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp @@ -184,7 +184,7 @@ bool HexagonGenExtract::convert(Instruction *In) { // The width of the extracted field is the minimum of the original bits // that remain after the shifts and the number of contiguous 1s in the mask. uint32_t W = std::min(U, T); - if (W == 0) + if (W == 0 || W == 1) return false; // Check if the extracted bits are contained within the mask that it is diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index bfdeec7c5cf3..4cf4af0be61f 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -162,6 +162,11 @@ def IsNPow2_64H: PatLeaf<(i64 imm), [{ return isPowerOf2_64(NV) && Log2_64(NV) >= 32; }]>; +class IsULE: PatLeaf<(i32 imm), + "uint64_t V = N->getZExtValue();" # + "return isUInt<" # Width # ">(V) && V <= " # Arg # ";" +>; + class IsUGT: PatLeaf<(i32 imm), "uint64_t V = N->getZExtValue();" # "return isUInt<" # Width # ">(V) && V > " # Arg # ";" @@ -1739,6 +1744,7 @@ let AddedComplexity = 20 in { // Complexity greater than and/or/xor (i32 (LoReg $Rss)))>; } + let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)), (S2_tstbit_i IntRegs:$Rs, imm:$u5)>; @@ -1750,6 +1756,22 @@ let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>; } +def: Pat<(and (srl I32:$Rs, u5_0ImmPred:$u5), 1), + (I1toI32 (S2_tstbit_i I32:$Rs, imm:$u5))>; +def: Pat<(and (srl I64:$Rss, IsULE<32,31>:$u6), 1), + (ToZext64 (I1toI32 (S2_tstbit_i (LoReg $Rss), imm:$u6)))>; +def: Pat<(and (srl I64:$Rss, IsUGT<32,31>:$u6), 1), + (ToZext64 (I1toI32 (S2_tstbit_i (HiReg $Rss), (UDEC32 $u6))))>; + +def N1toI32: OutPatFrag<(ops node:$Pu), (C2_muxii (i1 $Pu), 0, 1)>; + +def: Pat<(and (not (srl I32:$Rs, u5_0ImmPred:$u5)), 1), + (N1toI32 (S2_tstbit_i I32:$Rs, imm:$u5))>; +def: Pat<(and (not (srl I64:$Rss, IsULE<32,31>:$u6)), 1), + (ToZext64 (N1toI32 (S2_tstbit_i (LoReg $Rss), imm:$u6)))>; +def: Pat<(and (not (srl I64:$Rss, IsUGT<32,31>:$u6)), 1), + (ToZext64 (N1toI32 (S2_tstbit_i (HiReg $Rss), (UDEC32 $u6))))>; + let AddedComplexity = 20 in { // Complexity greater than compare reg-imm. def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)), (C2_bitsclri IntRegs:$Rs, imm:$u6)>; diff --git a/llvm/test/CodeGen/Hexagon/tstbit.ll b/llvm/test/CodeGen/Hexagon/tstbit.ll index 10ce8f950aa8..a21ad8d9a1fa 100644 --- a/llvm/test/CodeGen/Hexagon/tstbit.ll +++ b/llvm/test/CodeGen/Hexagon/tstbit.ll @@ -24,11 +24,11 @@ define i64 @is_upper_bit_clear_i64(i64 %x) #0 { ; CHECK-LABEL: is_upper_bit_clear_i64: ; CHECK: // %bb.0: ; CHECK-NEXT: { -; CHECK-NEXT: r1:0 = extractu(r1:0,#1,#37) +; CHECK-NEXT: p0 = tstbit(r1,#5) +; CHECK-NEXT: r1 = #0 ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r0 = togglebit(r0,#0) -; CHECK-NEXT: r1 = #0 +; CHECK-NEXT: r0 = mux(p0,#0,#1) ; CHECK-NEXT: jumpr r31 ; CHECK-NEXT: } %sh = lshr i64 %x, 37 @@ -41,11 +41,11 @@ define i64 @is_lower_bit_clear_i64(i64 %x) #0 { ; CHECK-LABEL: is_lower_bit_clear_i64: ; CHECK: // %bb.0: ; CHECK-NEXT: { -; CHECK-NEXT: r1:0 = extractu(r1:0,#1,#27) +; CHECK-NEXT: p0 = tstbit(r0,#27) +; CHECK-NEXT: r1 = #0 ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r0 = togglebit(r0,#0) -; CHECK-NEXT: r1 = #0 +; CHECK-NEXT: r0 = mux(p0,#0,#1) ; CHECK-NEXT: jumpr r31 ; CHECK-NEXT: } %sh = lshr i64 %x, 27 @@ -58,13 +58,10 @@ define i32 @is_bit_clear_i32(i32 %x) #0 { ; CHECK-LABEL: is_bit_clear_i32: ; CHECK: // %bb.0: ; CHECK-NEXT: { -; CHECK-NEXT: r1 = #-1 +; CHECK-NEXT: p0 = tstbit(r0,#27) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r1 ^= lsr(r0,#27) -; CHECK-NEXT: } -; CHECK-NEXT: { -; CHECK-NEXT: r0 = and(r1,#1) +; CHECK-NEXT: r0 = mux(p0,#0,#1) ; CHECK-NEXT: jumpr r31 ; CHECK-NEXT: } %sh = lshr i32 %x, 27 @@ -77,13 +74,10 @@ define i16 @is_bit_clear_i16(i16 %x) #0 { ; CHECK-LABEL: is_bit_clear_i16: ; CHECK: // %bb.0: ; CHECK-NEXT: { -; CHECK-NEXT: r1 = #-1 +; CHECK-NEXT: p0 = tstbit(r0,#7) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r1 ^= lsr(r0,#7) -; CHECK-NEXT: } -; CHECK-NEXT: { -; CHECK-NEXT: r0 = and(r1,#1) +; CHECK-NEXT: r0 = mux(p0,#0,#1) ; CHECK-NEXT: jumpr r31 ; CHECK-NEXT: } %sh = lshr i16 %x, 7 @@ -96,13 +90,10 @@ define i8 @is_bit_clear_i8(i8 %x) #0 { ; CHECK-LABEL: is_bit_clear_i8: ; CHECK: // %bb.0: ; CHECK-NEXT: { -; CHECK-NEXT: r1 = #-1 +; CHECK-NEXT: p0 = tstbit(r0,#3) ; CHECK-NEXT: } ; CHECK-NEXT: { -; CHECK-NEXT: r1 ^= lsr(r0,#3) -; CHECK-NEXT: } -; CHECK-NEXT: { -; CHECK-NEXT: r0 = and(r1,#1) +; CHECK-NEXT: r0 = mux(p0,#0,#1) ; CHECK-NEXT: jumpr r31 ; CHECK-NEXT: } %sh = lshr i8 %x, 3