From: Hal Finkel Date: Fri, 25 Jul 2014 21:45:17 +0000 (+0000) Subject: Canonicalization for @llvm.assume X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=5cb8ab5b5af971ee589f2659529a5759378c76ad;p=oota-llvm.git Canonicalization for @llvm.assume Adds simple logical canonicalization of assumption intrinsics to instcombine, currently: - invariant(a && b) -> invariant(a); invariant(b) - invariant(!(a || b)) -> invariant(!a); invariant(!b) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213977 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 658178d5914..8523c734549 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -994,6 +994,23 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { return EraseInstFromFunction(CI); break; } + case Intrinsic::assume: { + // Canonicalize assume(a && b) -> assume(a); assume(b); + Value *IIOperand = II->getArgOperand(0), *A, *B, + *AssumeIntrinsic = II->getCalledValue(); + if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) { + Builder->CreateCall(AssumeIntrinsic, A, II->getName()); + Builder->CreateCall(AssumeIntrinsic, B, II->getName()); + return EraseInstFromFunction(*II); + } + // assume(!(a || b)) -> assume(!a); assume(!b); + if (match(IIOperand, m_Not(m_Or(m_Value(A), m_Value(B))))) { + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(A), II->getName()); + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(B), II->getName()); + return EraseInstFromFunction(*II); + } + break; + } } return visitCallSite(II); diff --git a/test/Transforms/InstCombine/assume.ll b/test/Transforms/InstCombine/assume.ll new file mode 100644 index 00000000000..d65a8f7bc5e --- /dev/null +++ b/test/Transforms/InstCombine/assume.ll @@ -0,0 +1,43 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind +declare void @llvm.assume(i1) #1 + +; Function Attrs: nounwind uwtable +define i32 @can1(i1 %a, i1 %b, i1 %c) { +entry: + %and1 = and i1 %a, %b + %and = and i1 %and1, %c + tail call void @llvm.assume(i1 %and) + +; CHECK-LABEL: @can1 +; CHECK: call void @llvm.assume(i1 %a) +; CHECK: call void @llvm.assume(i1 %b) +; CHECK: call void @llvm.assume(i1 %c) +; CHECK: ret i32 + + ret i32 5 +} + +; Function Attrs: nounwind uwtable +define i32 @can2(i1 %a, i1 %b, i1 %c) { +entry: + %v = or i1 %a, %b + %w = xor i1 %v, 1 + tail call void @llvm.assume(i1 %w) + +; CHECK-LABEL: @can2 +; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true +; CHECK: call void @llvm.assume(i1 %[[V1]]) +; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true +; CHECK: call void @llvm.assume(i1 %[[V2]]) +; CHECK: ret i32 + + ret i32 5 +} + +attributes #0 = { nounwind uwtable } +attributes #1 = { nounwind } +