Sanjoy Das | 436e239 | 2015-11-07 01:55:53 +0000 | [diff] [blame] | 1 | ; RUN: opt -functionattrs -S < %s | FileCheck %s |
Fedor Sergeev | 6660fd0 | 2018-03-23 21:46:16 +0000 | [diff] [blame] | 2 | ; RUN: opt -passes=function-attrs -S < %s | FileCheck %s |
Sanjoy Das | 436e239 | 2015-11-07 01:55:53 +0000 | [diff] [blame] | 3 | |
| 4 | ; This checks for an iterator wraparound bug in FunctionAttrs. The previous |
| 5 | ; "incorrect" behavior was inferring readonly for the %x argument in @caller. |
| 6 | ; Inferring readonly for %x *is* actually correct, since @va_func is marked |
| 7 | ; readonly, but FunctionAttrs was inferring readonly for the wrong reasons (and |
| 8 | ; we _need_ the readonly on @va_func to trigger the problematic code path). It |
| 9 | ; is possible that in the future FunctionAttrs becomes smart enough to infer |
| 10 | ; readonly for %x for the right reasons, and at that point this test will have |
| 11 | ; to be marked invalid. |
| 12 | |
| 13 | declare void @llvm.va_start(i8*) |
| 14 | declare void @llvm.va_end(i8*) |
| 15 | |
| 16 | define void @va_func(i32* readonly %b, ...) readonly nounwind { |
| 17 | ; CHECK-LABEL: define void @va_func(i32* nocapture readonly %b, ...) |
| 18 | entry: |
| 19 | %valist = alloca i8 |
| 20 | call void @llvm.va_start(i8* %valist) |
| 21 | call void @llvm.va_end(i8* %valist) |
| 22 | %x = call i32 @caller(i32* %b) |
| 23 | ret void |
| 24 | } |
| 25 | |
| 26 | define i32 @caller(i32* %x) { |
| 27 | ; CHECK-LABEL: define i32 @caller(i32* nocapture %x) |
| 28 | entry: |
| 29 | call void(i32*,...) @va_func(i32* null, i32 0, i32 0, i32 0, i32* %x) |
| 30 | ret i32 42 |
| 31 | } |