1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=inline,instcombine %s | FileCheck %s --check-prefixes=CHECK,CHECK-INLINE 3; RUN: opt -S -passes=instcombine %s | FileCheck %s --check-prefixes=CHECK,CHECK-NOINLINE 4 5define ptr @widen_align_from_allocalign_callsite() { 6; CHECK-LABEL: @widen_align_from_allocalign_callsite( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[CALL:%.*]] = tail call align 64 ptr @my_aligned_alloc_2(i32 noundef 320, i32 allocalign noundef 64) 9; CHECK-NEXT: ret ptr [[CALL]] 10; 11entry: 12 13 %call = tail call align 16 ptr @my_aligned_alloc_2(i32 noundef 320, i32 allocalign noundef 64) 14 ret ptr %call 15} 16 17define ptr @widen_align_from_allocalign() { 18; CHECK-LABEL: @widen_align_from_allocalign( 19; CHECK-NEXT: entry: 20; CHECK-NEXT: [[CALL:%.*]] = tail call align 64 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 64) 21; CHECK-NEXT: ret ptr [[CALL]] 22; 23entry: 24 25 %call = tail call align 16 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 64) 26 ret ptr %call 27} 28 29define ptr @dont_narrow_align_from_allocalign() { 30; CHECK-LABEL: @dont_narrow_align_from_allocalign( 31; CHECK-NEXT: entry: 32; CHECK-NEXT: [[CALL:%.*]] = tail call align 16 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 8) 33; CHECK-NEXT: ret ptr [[CALL]] 34; 35entry: 36 %call = tail call align 16 ptr @my_aligned_alloc(i32 noundef 320, i32 noundef 8) 37 ret ptr %call 38} 39 40define ptr @my_aligned_alloc_3(i32 noundef %foo, i32 allocalign %alignment) { 41; CHECK-LABEL: @my_aligned_alloc_3( 42; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @my_aligned_alloc_2(i32 noundef [[FOO:%.*]], i32 noundef [[ALIGNMENT:%.*]]) 43; CHECK-NEXT: ret ptr [[CALL]] 44; 45 %call = tail call ptr @my_aligned_alloc_2(i32 noundef %foo, i32 noundef %alignment) 46 ret ptr %call 47} 48 49; -passes=inline is able to make my_aligned_alloc_3's arguments disappear and directly 50; call my_aligned_alloc_2, but the latter has no allocalign so the alignment just 51; disappears. This is conservatively correct but undesirable because we can't 52; figure out the `align 128` on the return value once the call is directly on 53; my_aligned_alloc_2. Note that this is a simplified version of what happens 54; with _mm_malloc which calls posix_memalign. 55define ptr @allocalign_disappears() { 56; CHECK-INLINE-LABEL: @allocalign_disappears( 57; CHECK-INLINE-NEXT: [[CALL_I:%.*]] = tail call ptr @my_aligned_alloc_2(i32 noundef 42, i32 noundef 128) 58; CHECK-INLINE-NEXT: ret ptr [[CALL_I]] 59; 60; CHECK-NOINLINE-LABEL: @allocalign_disappears( 61; CHECK-NOINLINE-NEXT: [[CALL:%.*]] = tail call align 128 ptr @my_aligned_alloc_3(i32 42, i32 128) 62; CHECK-NOINLINE-NEXT: ret ptr [[CALL]] 63; 64 %call = tail call ptr @my_aligned_alloc_3(i32 42, i32 128) 65 ret ptr %call 66} 67 68declare ptr @my_aligned_alloc(i32 noundef, i32 allocalign noundef) 69declare ptr @my_aligned_alloc_2(i32 noundef, i32 noundef) 70