[llvm] r310159 - [InstCombine] In foldSelectICmpAnd, if we need to to truncate from the 'and' type to the 'select' type, do it after shifting right instead of just bailing.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 4 18:45:17 PDT 2017


Author: ctopper
Date: Fri Aug  4 18:45:17 2017
New Revision: 310159

URL: http://llvm.org/viewvc/llvm-project?rev=310159&view=rev
Log:
[InstCombine] In foldSelectICmpAnd, if we need to to truncate from the 'and' type to the 'select' type, do it after shifting right instead of just bailing.

Previously we were always trying to emit the zext or truncate before any shift. This meant if the 'and' mask was larger than the size of the truncate we would skip the transformation.

Now we shift the result of the and right first leaving the bit within the range of the truncate.

This matches what we are doing in foldSelectICmpAndOr for the same problem.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/select-with-bitwise-ops.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=310159&r1=310158&r2=310159&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Aug  4 18:45:17 2017
@@ -640,16 +640,16 @@ static Value *foldSelectICmpAnd(const Se
   unsigned AndZeros = AndRHS->getValue().logBase2();
 
   // If types don't match we can still convert the select by introducing a zext
-  // or a trunc of the 'and'. The trunc case requires that all of the truncated
-  // bits are zero, we can figure that out by looking at the 'and' mask.
-  if (AndZeros >= ValC.getBitWidth())
-    return nullptr;
-
-  Value *V = Builder.CreateZExtOrTrunc(LHS, SI.getType());
-  if (ValZeros > AndZeros)
+  // or a trunc of the 'and'.
+  Value *V = LHS;
+  if (ValZeros > AndZeros) {
+    V = Builder.CreateZExtOrTrunc(V, SI.getType());
     V = Builder.CreateShl(V, ValZeros - AndZeros);
-  else if (ValZeros < AndZeros)
+  } else if (ValZeros < AndZeros) {
     V = Builder.CreateLShr(V, AndZeros - ValZeros);
+    V = Builder.CreateZExtOrTrunc(V, SI.getType());
+  } else
+    V = Builder.CreateZExtOrTrunc(V, SI.getType());
 
   // Okay, now we know that everything is set up, we just don't know whether we
   // have a icmp_ne or icmp_eq and whether the true or false val is the zero.

Modified: llvm/trunk/test/Transforms/InstCombine/select-with-bitwise-ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-with-bitwise-ops.ll?rev=310159&r1=310158&r2=310159&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-with-bitwise-ops.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-with-bitwise-ops.ll Fri Aug  4 18:45:17 2017
@@ -256,11 +256,11 @@ define i32 @select_icmp_x_and_2147483648
 
 define i32 @test65(i64 %x) {
 ; CHECK-LABEL: @test65(
-; CHECK-NEXT:    [[X_TR:%.*]] = trunc i64 %x to i32
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X_TR]], 3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], 42
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 3
+; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 2
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], 42
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = and i64 %x, 16
   %2 = icmp ne i64 %1, 0
@@ -270,10 +270,11 @@ define i32 @test65(i64 %x) {
 
 define i32 @test66(i64 %x) {
 ; CHECK-LABEL: @test66(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i64 %x, 4294967296
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0
-; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 31
+; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 2
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], 42
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = and i64 %x, 4294967296
   %2 = icmp ne i64 %1, 0




More information about the llvm-commits mailing list