1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[InstCombine] Remove redundant @llvm.assume intrinsics

For any @llvm.assume intrinsic, if there is another which dominates it and uses
the same condition, then it is redundant and can be removed. While this does
not alter the semantics of the @llvm.assume intrinsics, it makes subsequent
handling more efficient (and the resulting IR easier to read).

llvm-svn: 219067
This commit is contained in:
Hal Finkel 2014-10-04 21:27:06 +00:00
parent d58cb7b41a
commit 59318e2605
2 changed files with 72 additions and 0 deletions

View File

@ -16,6 +16,7 @@
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/Local.h"
@ -1016,6 +1017,22 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
II->getName());
return EraseInstFromFunction(*II);
}
// If there is a dominating assume with the same condition as this one,
// then this one is redundant, and should be removed.
if (DT) {
for (User *U : IIOperand->users()) {
Instruction *User = dyn_cast<Instruction>(U);
if (!User || User == II)
continue;
if (match(User,
m_Intrinsic<Intrinsic::assume>(m_Specific(IIOperand))) &&
DT->dominates(User, II))
return EraseInstFromFunction(*II);
}
}
break;
}
}

View File

@ -0,0 +1,55 @@
; RUN: opt -domtree -instcombine -loops -S < %s | FileCheck %s
; Note: The -loops above can be anything that requires the domtree, and is
; necessary to work around a pass-manager bug.
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.s = type { double* }
; Function Attrs: nounwind uwtable
define void @_Z3fooR1s(%struct.s* nocapture readonly dereferenceable(8) %x) #0 {
; CHECK-LABEL: @_Z3fooR1s
; CHECK: call void @llvm.assume
; CHECK-NOT: call void @llvm.assume
entry:
%a = getelementptr inbounds %struct.s* %x, i64 0, i32 0
%0 = load double** %a, align 8
%ptrint = ptrtoint double* %0 to i64
%maskedptr = and i64 %ptrint, 31
%maskcond = icmp eq i64 %maskedptr, 0
br label %for.body
for.body: ; preds = %for.body, %entry
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next.1, %for.body ]
tail call void @llvm.assume(i1 %maskcond)
%arrayidx = getelementptr inbounds double* %0, i64 %indvars.iv
%1 = load double* %arrayidx, align 16
%add = fadd double %1, 1.000000e+00
tail call void @llvm.assume(i1 %maskcond)
%mul = fmul double %add, 2.000000e+00
store double %mul, double* %arrayidx, align 16
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
tail call void @llvm.assume(i1 %maskcond)
%arrayidx.1 = getelementptr inbounds double* %0, i64 %indvars.iv.next
%2 = load double* %arrayidx.1, align 8
%add.1 = fadd double %2, 1.000000e+00
tail call void @llvm.assume(i1 %maskcond)
%mul.1 = fmul double %add.1, 2.000000e+00
store double %mul.1, double* %arrayidx.1, align 8
%indvars.iv.next.1 = add nuw nsw i64 %indvars.iv.next, 1
%exitcond.1 = icmp eq i64 %indvars.iv.next, 1599
br i1 %exitcond.1, label %for.end, label %for.body
for.end: ; preds = %for.body
ret void
}
; Function Attrs: nounwind
declare void @llvm.assume(i1) #1
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind }