1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
Nikita Popov f73282e3d5 [InstCombine] Simplify calls with "returned" attribute
If a call argument has the "returned" attribute, we can simplify
the call to the value of that argument. This was already partially
handled by InstSimplify/InstCombine for the case where the argument
is an integer constant, and the result is thus known via known bits.
The non-constant (or non-int) argument cases weren't handled though.

This previously landed as an InstSimplify transform, but was reverted
due to assertion failures when compiling the Linux kernel. The reason
is that simplifying a call to another call breaks assumptions in
call graph updating during inlining. As the code is not easy to fix,
and there is no particularly strong motivation for having this in
InstSimplify, the transform is only performed in InstCombine instead.

Differential Revision: https://reviews.llvm.org/D75815
2020-03-20 10:23:39 +01:00

50 lines
1.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -S -O3 -o - %s | FileCheck %s
; PR44154: LLVM c3b06d0c393e caused the body of @main to be replaced with
; unreachable. Check that we perform the expected calls and optimizations.
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i32 @main(i32 %argc, i8** %argv) #0 {
; CHECK-LABEL: define {{[^@]+}}@main
; CHECK-SAME: (i32 [[ARGC:%.*]], i8** nocapture readnone [[ARGV:%.*]]) local_unnamed_addr #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ARGC]], 2
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 0, i32 [[ARGC]]
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
;
entry:
%0 = getelementptr inbounds i8*, i8** %argv, i32 0
%ptr = load i8*, i8** %0
%1 = call i32 @compute(i8* %ptr, i32 %argc)
%2 = icmp slt i32 %argc, 2
br i1 %2, label %done, label %do_work
do_work:
%3 = icmp eq i8* %ptr, null
br i1 %3, label %null, label %done
null:
call void @call_if_null(i8* %ptr)
br label %done
done:
%retval = phi i32 [0, %entry], [%1, %do_work], [%1, %null]
ret i32 %retval
}
define i32 @compute(i8* nonnull %ptr, i32 %x) #1 {
; CHECK-LABEL: define {{[^@]+}}@compute
; CHECK-SAME: (i8* nocapture nonnull readnone [[PTR:%.*]], i32 returned [[X:%.*]]) local_unnamed_addr #1
; CHECK-NEXT: ret i32 [[X]]
;
ret i32 %x
}
declare void @call_if_null(i8* %ptr) #0
attributes #0 = { nounwind }
attributes #1 = { noinline nounwind readonly }