Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -1358,6 +1358,12 @@ if (IntrinsicInst *II = dyn_cast(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; Index: test/Transforms/InstCombine/bswap-known-bits.ll =================================================================== --- test/Transforms/InstCombine/bswap-known-bits.ll +++ test/Transforms/InstCombine/bswap-known-bits.ll @@ -0,0 +1,46 @@ +; 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 aparently only in instcombine. + +declare i16 @llvm.bswap.i16(i16) + +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 uge i16 %b, 1 + ret i1 %res +} + +define i1 @test4(i16 %arg) { +; CHECK-LABEL: @test4 +; 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 +} Index: test/Transforms/InstSimplify/bswap.ll =================================================================== --- test/Transforms/InstSimplify/bswap.ll +++ test/Transforms/InstSimplify/bswap.ll @@ -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 +}