From 62611fd3f70d32e16899d3783784be11e3a9c344 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 25 Jul 2016 22:04:58 +0000 Subject: [PATCH] [InstSimplify] Add support for bitcasts BitCasts of BitCasts can be folded away as can BitCasts which don't change the type of the operand. llvm-svn: 276698 --- llvm/include/llvm/Analysis/InstructionSimplify.h | 7 ++++++ llvm/lib/Analysis/InstructionSimplify.cpp | 29 ++++++++++++++++++++++++ llvm/test/Transforms/GVN/pr14166.ll | 4 +--- llvm/test/Transforms/InstSimplify/cast.ll | 27 ++++++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/InstSimplify/cast.ll diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h index 410fa41..06d7d80 100644 --- a/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -245,6 +245,13 @@ namespace llvm { AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr); + /// Given operands for an BitCastInst, fold the result or return null. + Value *SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr, + const DominatorTree *DT = nullptr, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr); + //=== Helper functions for higher up the class hierarchy. diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 981fb97..8fde9c7 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -70,6 +70,7 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &, static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned); static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned); static Value *SimplifyTruncInst(Value *, Type *, const Query &, unsigned); +static Value *SimplifyBitCastInst(Value *, Type *, const Query &, unsigned); /// For a boolean type, or a vector of boolean type, return false, or /// a vector with every element false, as appropriate for the type. @@ -3810,6 +3811,30 @@ Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL, RecursionLimit); } +static Value *SimplifyBitCastInst(Value *Op, Type *Ty, const Query &Q, unsigned) { + if (auto *C = dyn_cast(Op)) + return ConstantFoldCastOperand(Instruction::BitCast, C, Ty, Q.DL); + + // bitcast x -> x + if (Op->getType() == Ty) + return Op; + + // bitcast(bitcast x) -> x + if (auto *BC = dyn_cast(Op)) + if (BC->getOperand(0)->getType() == Ty) + return BC->getOperand(0); + + return nullptr; +} + +Value *llvm::SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL, + const TargetLibraryInfo *TLI, + const DominatorTree *DT, AssumptionCache *AC, + const Instruction *CxtI) { + return ::SimplifyBitCastInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI), + RecursionLimit); +} + //=== Helper functions for higher up the class hierarchy. /// Given operands for a BinaryOperator, see if we can fold the result. @@ -4280,6 +4305,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL, Result = SimplifyTruncInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I); break; + case Instruction::BitCast: + Result = + SimplifyBitCastInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I); + break; } // In general, it is possible for computeKnownBits to determine all bits in a diff --git a/llvm/test/Transforms/GVN/pr14166.ll b/llvm/test/Transforms/GVN/pr14166.ll index ec1b171..2e77496 100644 --- a/llvm/test/Transforms/GVN/pr14166.ll +++ b/llvm/test/Transforms/GVN/pr14166.ll @@ -18,9 +18,7 @@ define <2 x i32> @test1() { ; CHECK: %v4 = bitcast <2 x i32>* %v1 to <2 x i8*>* ; CHECK: store <2 x i8*> %v3, <2 x i8*>* %v4 ; CHECK: %1 = ptrtoint <2 x i8*> %v3 to <2 x i32> -; CHECK: %2 = bitcast <2 x i32> %1 to i64 -; CHECK: %3 = bitcast i64 %2 to <2 x i32> -; CHECK: ret <2 x i32> %3 +; CHECK: ret <2 x i32> %1 } declare void @anything(<2 x i32>*) diff --git a/llvm/test/Transforms/InstSimplify/cast.ll b/llvm/test/Transforms/InstSimplify/cast.ll new file mode 100644 index 0000000..a656854 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/cast.ll @@ -0,0 +1,27 @@ +; RUN: opt -S -instsimplify < %s | FileCheck %s + +define i1 @test1(i1 %V) { +entry: + %Z = zext i1 %V to i32 + %T = trunc i32 %Z to i1 + ret i1 %T +; CHECK-LABEL: define i1 @test1( +; CHECK: ret i1 %V +} + +define i8* @test2(i8* %V) { +entry: + %BC1 = bitcast i8* %V to i32* + %BC2 = bitcast i32* %BC1 to i8* + ret i8* %BC2 +; CHECK-LABEL: define i8* @test2( +; CHECK: ret i8* %V +} + +define i8* @test3(i8* %V) { +entry: + %BC = bitcast i8* %V to i8* + ret i8* %BC +; CHECK-LABEL: define i8* @test3( +; CHECK: ret i8* %V +} -- 2.7.4