36 import org.graalvm.compiler.phases.common.CanonicalizerPhase; |
36 import org.graalvm.compiler.phases.common.CanonicalizerPhase; |
37 import org.graalvm.compiler.phases.common.inlining.InliningPhase; |
37 import org.graalvm.compiler.phases.common.inlining.InliningPhase; |
38 import org.graalvm.compiler.phases.tiers.HighTierContext; |
38 import org.graalvm.compiler.phases.tiers.HighTierContext; |
39 import org.graalvm.compiler.replacements.nodes.BitScanReverseNode; |
39 import org.graalvm.compiler.replacements.nodes.BitScanReverseNode; |
40 |
40 |
|
41 import jdk.vm.ci.aarch64.AArch64; |
41 import jdk.vm.ci.amd64.AMD64; |
42 import jdk.vm.ci.amd64.AMD64; |
42 import jdk.vm.ci.code.Architecture; |
43 import jdk.vm.ci.code.Architecture; |
43 import jdk.vm.ci.meta.JavaKind; |
44 import jdk.vm.ci.meta.JavaKind; |
44 import jdk.vm.ci.sparc.SPARC; |
45 import jdk.vm.ci.sparc.SPARC; |
45 |
46 |
57 |
58 |
58 /* |
59 /* |
59 * Tests for BitCountNode canonicalizations. |
60 * Tests for BitCountNode canonicalizations. |
60 */ |
61 */ |
61 |
62 |
|
63 /** |
|
64 * Determines if the current VM context supports intrinsics for the {@code bitCount} methods in |
|
65 * {@link Integer} and {@link Long}. |
|
66 */ |
|
67 public static boolean isBitCountIntrinsicSupported(Architecture arch) { |
|
68 if (arch instanceof AMD64) { |
|
69 AMD64 amd64 = (AMD64) arch; |
|
70 return amd64.getFeatures().contains(AMD64.CPUFeature.POPCNT); |
|
71 } else { |
|
72 // Even though there are AArch64 intrinsics for bitCount, they do |
|
73 // not use BitCountNode. |
|
74 return arch instanceof SPARC; |
|
75 } |
|
76 } |
|
77 |
|
78 /** |
|
79 * Determines if the current VM context supports intrinsics for the {@code numberOfLeadingZeros} |
|
80 * methods in {@link Integer} and {@link Long}. |
|
81 */ |
|
82 public static boolean isNumberLeadingZerosIntrinsicSupported(Architecture arch) { |
|
83 if (arch instanceof AMD64) { |
|
84 AMD64 amd64 = (AMD64) arch; |
|
85 return amd64.getFeatures().contains(AMD64.CPUFeature.LZCNT) && amd64.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction); |
|
86 } else { |
|
87 return arch instanceof SPARC || arch instanceof AArch64; |
|
88 } |
|
89 } |
|
90 |
|
91 /** |
|
92 * Determines if the current VM context supports intrinsics for the |
|
93 * {@code numberOfTrailingZeros} methods in {@link Integer} and {@link Long}. |
|
94 */ |
|
95 public static boolean isNumberTrailingZerosIntrinsicSupported(Architecture arch) { |
|
96 if (arch instanceof AMD64) { |
|
97 AMD64 amd64 = (AMD64) arch; |
|
98 return amd64.getFeatures().contains(AMD64.CPUFeature.BMI1) && amd64.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction); |
|
99 } else { |
|
100 return arch instanceof SPARC || arch instanceof AArch64; |
|
101 } |
|
102 } |
|
103 |
62 public static int bitCountIntConstantSnippet() { |
104 public static int bitCountIntConstantSnippet() { |
63 return Integer.bitCount(INT_CONSTANT_1) + Integer.bitCount(INT_CONSTANT_2) + Integer.bitCount(INT_CONSTANT_3); |
105 return Integer.bitCount(INT_CONSTANT_1) + Integer.bitCount(INT_CONSTANT_2) + Integer.bitCount(INT_CONSTANT_3); |
64 } |
106 } |
65 |
107 |
66 @Test |
108 @Test |
77 return Integer.bitCount(v & 0xFFFFFF | 0xFF); |
119 return Integer.bitCount(v & 0xFFFFFF | 0xFF); |
78 } |
120 } |
79 |
121 |
80 @Test |
122 @Test |
81 public void testBitCountInt() { |
123 public void testBitCountInt() { |
82 Architecture arch = getBackend().getTarget().arch; |
124 Assume.assumeTrue(isBitCountIntrinsicSupported(getBackend().getTarget().arch)); |
83 boolean isAmd64WithPopCount = arch instanceof AMD64 && ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.POPCNT); |
|
84 boolean isSparc = arch instanceof SPARC; |
|
85 Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc); |
|
86 ValueNode result = parseAndInline("bitCountIntSnippet"); |
125 ValueNode result = parseAndInline("bitCountIntSnippet"); |
87 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp(NodeView.DEFAULT)); |
126 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp(NodeView.DEFAULT)); |
88 } |
127 } |
89 |
128 |
90 public static int bitCountIntEmptySnippet(int v) { |
129 public static int bitCountIntEmptySnippet(int v) { |
91 return Integer.bitCount(v & 0xFFFFFF); |
130 return Integer.bitCount(v & 0xFFFFFF); |
92 } |
131 } |
93 |
132 |
94 @Test |
133 @Test |
95 public void testBitCountIntEmpty() { |
134 public void testBitCountIntEmpty() { |
96 Architecture arch = getBackend().getTarget().arch; |
135 Assume.assumeTrue(isBitCountIntrinsicSupported(getBackend().getTarget().arch)); |
97 boolean isAmd64WithPopCount = arch instanceof AMD64 && ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.POPCNT); |
|
98 boolean isSparc = arch instanceof SPARC; |
|
99 Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc); |
|
100 ValueNode result = parseAndInline("bitCountIntEmptySnippet"); |
136 ValueNode result = parseAndInline("bitCountIntEmptySnippet"); |
101 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp(NodeView.DEFAULT)); |
137 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp(NodeView.DEFAULT)); |
102 } |
138 } |
103 |
139 |
104 @Test |
140 @Test |
111 return Long.bitCount(v & 0xFFFFFFFFFFL | 0xFFL); |
147 return Long.bitCount(v & 0xFFFFFFFFFFL | 0xFFL); |
112 } |
148 } |
113 |
149 |
114 @Test |
150 @Test |
115 public void testBitCountLong() { |
151 public void testBitCountLong() { |
116 Architecture arch = getBackend().getTarget().arch; |
152 Assume.assumeTrue(isBitCountIntrinsicSupported(getBackend().getTarget().arch)); |
117 boolean isAmd64WithPopCount = arch instanceof AMD64 && ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.POPCNT); |
|
118 boolean isSparc = arch instanceof SPARC; |
|
119 Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc); |
|
120 ValueNode result = parseAndInline("bitCountLongSnippet"); |
153 ValueNode result = parseAndInline("bitCountLongSnippet"); |
121 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp(NodeView.DEFAULT)); |
154 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp(NodeView.DEFAULT)); |
122 } |
155 } |
123 |
156 |
124 public static int bitCountLongEmptySnippet(long v) { |
157 public static int bitCountLongEmptySnippet(long v) { |
125 return Long.bitCount(v & 0xFFFFFFFFFFL); |
158 return Long.bitCount(v & 0xFFFFFFFFFFL); |
126 } |
159 } |
127 |
160 |
128 @Test |
161 @Test |
129 public void testBitCountLongEmpty() { |
162 public void testBitCountLongEmpty() { |
130 Architecture arch = getBackend().getTarget().arch; |
163 Assume.assumeTrue(isBitCountIntrinsicSupported(getBackend().getTarget().arch)); |
131 boolean isAmd64WithPopCount = arch instanceof AMD64 && ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.POPCNT); |
|
132 boolean isSparc = arch instanceof SPARC; |
|
133 Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc); |
|
134 ValueNode result = parseAndInline("bitCountLongEmptySnippet"); |
164 ValueNode result = parseAndInline("bitCountLongEmptySnippet"); |
135 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp(NodeView.DEFAULT)); |
165 Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp(NodeView.DEFAULT)); |
136 } |
166 } |
137 |
167 |
138 /* |
168 /* |