Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2878,6 +2878,23 @@ 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; } } Index: llvm/trunk/test/Transforms/InstCombine/call-guard.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/call-guard.ll +++ llvm/trunk/test/Transforms/InstCombine/call-guard.ll @@ -28,3 +28,23 @@ 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 +}