Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2870,6 +2870,16 @@ // TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...) break; } + + case Intrinsic::experimental_guard: { + Value *IIOperand = II->getArgOperand(0); + + // Remove a guard if it is immediately followed by an identical guard. + if (match(II->getNextNode(), + m_Intrinsic(m_Specific(IIOperand)))) + return eraseInstFromFunction(*II); + break; + } } return visitCallSite(II); Index: test/Transforms/InstCombine/call-guard.ll =================================================================== --- test/Transforms/InstCombine/call-guard.ll +++ test/Transforms/InstCombine/call-guard.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @llvm.experimental.guard(i1, ...) + +define void @test_guard_adjacent(i1 %A) { +; CHECK-LABEL: @test_guard_adjacent( +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ] +; CHECK-NEXT: ret void + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ] + ret void +}