From 7f5fbe3e3eb93ce5dbf33617d6b89fed0342942c Mon Sep 17 00:00:00 2001 From: Artur Pilipenko Date: Wed, 25 Jan 2017 14:20:52 +0000 Subject: [PATCH] [InstCombine] Canonicalize guards for AND condition This is a partial fix for Bug 31520 - [guards] canonicalize guards in instcombine Reviewed By: apilipenko Differential Revision: https://reviews.llvm.org/D29074 Patch by Maxim Kazantsev. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293058 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCalls.cpp | 17 ++++++++++++++++ test/Transforms/InstCombine/call-guard.ll | 20 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 679596766fc..523b35c31bb 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2878,6 +2878,23 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { if (match(II->getNextNode(), m_Intrinsic(m_Specific(IIOperand)))) return eraseInstFromFunction(*II); + + // Canonicalize guard(a && b) -> guard(a); guard(b); + // Note: New guard intrinsics created here are registered by + // the InstCombineIRInserter object. + Function *GuardIntrinsic = II->getCalledFunction(); + Value *A, *B; + OperandBundleDef DeoptOB(*II->getOperandBundle(LLVMContext::OB_deopt)); + if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) { + CallInst *GuardA = + Builder->CreateCall(GuardIntrinsic, A, {DeoptOB}, II->getName()); + CallInst *GuardB = + Builder->CreateCall(GuardIntrinsic, B, {DeoptOB}, II->getName()); + auto CC = II->getCallingConv(); + GuardA->setCallingConv(CC); + GuardB->setCallingConv(CC); + return eraseInstFromFunction(*II); + } break; } } diff --git a/test/Transforms/InstCombine/call-guard.ll b/test/Transforms/InstCombine/call-guard.ll index 18da465e606..d392ede574f 100644 --- a/test/Transforms/InstCombine/call-guard.ll +++ b/test/Transforms/InstCombine/call-guard.ll @@ -28,3 +28,23 @@ define void @test_guard_adjacent_neg(i1 %A, i1 %B) { call void(i1, ...) @llvm.experimental.guard( i1 %B )[ "deopt"() ] ret void } + +define void @test_guard_and(i1 %A, i1 %B) { +; CHECK-LABEL: @test_guard_and( +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %B) [ "deopt"() ] +; CHECK-NEXT: ret void + %C = and i1 %A, %B + call void(i1, ...) @llvm.experimental.guard( i1 %C )[ "deopt"() ] + ret void +} + +define void @test_guard_and_non_default_cc(i1 %A, i1 %B) { +; CHECK-LABEL: @test_guard_and_non_default_cc( +; CHECK-NEXT: call cc99 void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ] +; CHECK-NEXT: call cc99 void (i1, ...) @llvm.experimental.guard(i1 %B) [ "deopt"() ] +; CHECK-NEXT: ret void + %C = and i1 %A, %B + call cc99 void(i1, ...) @llvm.experimental.guard( i1 %C )[ "deopt"() ] + ret void +} -- 2.40.0