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