[llvm] r249453 - Extend known bits to understand @llvm.bswap

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 13:20:46 PDT 2015


Author: reames
Date: Tue Oct  6 15:20:45 2015
New Revision: 249453

URL: http://llvm.org/viewvc/llvm-project?rev=249453&view=rev
Log:
Extend known bits to understand @llvm.bswap

This is a cleaned up patch from the one written by John Regehr based on the findings of the Souper superoptimizer.

When writing tests, I was surprised to find that instsimplify apparently doesn't know how to collapse bit test sequences based purely on known bits. This required me to split my tests across both instsimplify and instcombine.

Differential Revision: http://reviews.llvm.org/D13250


Added:
    llvm/trunk/test/Transforms/InstCombine/bswap-known-bits.ll
    llvm/trunk/test/Transforms/InstSimplify/bswap.ll
Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=249453&r1=249452&r2=249453&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Oct  6 15:20:45 2015
@@ -1358,6 +1358,12 @@ static void computeKnownBitsFromOperator
     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
       switch (II->getIntrinsicID()) {
       default: break;
+      case Intrinsic::bswap:
+        computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, DL,
+                         Depth + 1, Q);
+        KnownZero |= KnownZero2.byteSwap();
+        KnownOne |= KnownOne2.byteSwap();
+        break;
       case Intrinsic::ctlz:
       case Intrinsic::cttz: {
         unsigned LowBits = Log2_32(BitWidth)+1;

Added: llvm/trunk/test/Transforms/InstCombine/bswap-known-bits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/bswap-known-bits.ll?rev=249453&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/bswap-known-bits.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/bswap-known-bits.ll Tue Oct  6 15:20:45 2015
@@ -0,0 +1,47 @@
+; RUN: opt < %s -S -instcombine | FileCheck %s
+; Note: This is testing functionality in computeKnownBits.  I'd have rather
+; used instsimplify, but the bit test folding is apparently only in instcombine.
+
+declare i16 @llvm.bswap.i16(i16)
+declare i32 @llvm.bswap.i32(i32)
+
+define i1 @test1(i16 %arg) {
+; CHECK-LABEL: @test1
+; CHECK: ret i1 true
+  %a = or i16 %arg, 511
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %and = and i16 %b, 256
+  %res = icmp eq i16 %and, 256
+  ret i1 %res
+}
+
+define i1 @test2(i16 %arg) {
+; CHECK-LABEL: @test2
+; CHECK: ret i1 true
+  %a = or i16 %arg, 1
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %and = and i16 %b, 256
+  %res = icmp eq i16 %and, 256
+  ret i1 %res
+}
+
+
+define i1 @test3(i16 %arg) {
+; CHECK-LABEL: @test3
+; CHECK: ret i1 true
+  %a = or i16 %arg, 256
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %and = and i16 %b, 1
+  %res = icmp eq i16 %and, 1
+  ret i1 %res
+}
+
+define i1 @test4(i32 %arg) {
+; CHECK-LABEL: @test4
+; CHECK: ret i1 true
+  %a = or i32 %arg, 2147483647  ; i32_MAX
+  %b = call i32 @llvm.bswap.i32(i32 %a)
+  %and = and i32 %b, 127
+  %res = icmp eq i32 %and, 127
+  ret i1 %res
+}

Added: llvm/trunk/test/Transforms/InstSimplify/bswap.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/bswap.ll?rev=249453&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/bswap.ll (added)
+++ llvm/trunk/test/Transforms/InstSimplify/bswap.ll Tue Oct  6 15:20:45 2015
@@ -0,0 +1,41 @@
+; RUN: opt < %s -S -instsimplify | FileCheck %s
+
+declare i16 @llvm.bswap.i16(i16)
+
+define i1 @test1(i16 %arg) {
+; CHECK-LABEL: @test1
+; CHECK: ret i1 false
+  %a = or i16 %arg, 1
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %res = icmp eq i16 %b, 0
+  ret i1 %res
+}
+
+define i1 @test2(i16 %arg) {
+; CHECK-LABEL: @test2
+; CHECK: ret i1 false
+  %a = or i16 %arg, 1024
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %res = icmp eq i16 %b, 0
+  ret i1 %res
+}
+
+define i1 @test3(i16 %arg) {
+; CHECK-LABEL: @test3
+; CHECK: ret i1 false
+  %a = and i16 %arg, 1
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %and = and i16 %b, 1
+  %res = icmp eq i16 %and, 1
+  ret i1 %res
+}
+
+define i1 @test4(i16 %arg) {
+; CHECK-LABEL: @test4
+; CHECK: ret i1 false
+  %a = and i16 %arg, 511
+  %b = call i16 @llvm.bswap.i16(i16 %a)
+  %and = and i16 %b, 256
+  %res = icmp eq i16 %and, 1
+  ret i1 %res
+}




More information about the llvm-commits mailing list