|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
|
|
|
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
|
|
|
|
|
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
|
|
|
|
|
; RUN: opt -passes='require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=WITH-AC
|
|
|
|
|
; RUN: opt -passes='require<domtree>,require<assumptions>,assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=CROSS-BLOCK
|
|
|
|
|
|
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
|
|
|
|
|
@ -22,8 +24,8 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
|
|
|
|
; BASIC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
|
|
|
|
; BASIC-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
|
|
|
|
; BASIC-NEXT: call void @func_strbool(i32* [[P1]])
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 16) ]
|
|
|
|
|
; BASIC-NEXT: call void @func(i32* dereferenceable(16) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
|
|
|
|
; BASIC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
|
|
|
|
; BASIC-NEXT: call void @func_many(i32* align 8 [[P1]])
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2:%.*]], i64 8), "nonnull"(i32* [[P3:%.*]]) ]
|
|
|
|
@ -43,8 +45,8 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
|
|
|
|
; ALL-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
|
|
|
|
; ALL-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
|
|
|
|
; ALL-NEXT: call void @func_strbool(i32* [[P1]])
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 16) ]
|
|
|
|
|
; ALL-NEXT: call void @func(i32* dereferenceable(16) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
|
|
|
|
; ALL-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "norecurse"(), "nounwind"(), "willreturn"() ]
|
|
|
|
|
; ALL-NEXT: call void @func_many(i32* align 8 [[P1]])
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2:%.*]], i64 8), "nonnull"(i32* [[P3:%.*]]), "nounwind"() ]
|
|
|
|
@ -53,13 +55,56 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
|
|
|
|
; ALL-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
|
|
|
|
; ALL-NEXT: ret void
|
|
|
|
|
;
|
|
|
|
|
; WITH-AC-LABEL: @test(
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P:%.*]], i64 16), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1:%.*]], i64 12) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) #0
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
|
|
|
|
; WITH-AC-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
|
|
|
|
; WITH-AC-NEXT: call void @func_strbool(i32* [[P1]])
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func_many(i32* align 8 [[P1]])
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2:%.*]], i64 8), "nonnull"(i32* [[P3:%.*]]) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; WITH-AC-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
|
|
|
|
; WITH-AC-NEXT: ret void
|
|
|
|
|
;
|
|
|
|
|
; CROSS-BLOCK-LABEL: @test(
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P:%.*]], i64 16), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1:%.*]], i64 12) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) #0
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func_strbool(i32* [[P1]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func_many(i32* align 8 [[P1]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2:%.*]], i64 8), "nonnull"(i32* [[P3:%.*]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
|
|
|
|
; CROSS-BLOCK-NEXT: ret void
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
call void @func(i32* nonnull dereferenceable(16) %P, i32* null)
|
|
|
|
|
call void @func(i32* dereferenceable(12) %P1, i32* nonnull %P)
|
|
|
|
|
call void @func_cold(i32* dereferenceable(12) %P1) cold
|
|
|
|
|
call void @func_cold(i32* dereferenceable(12) %P1)
|
|
|
|
|
call void @func(i32* %P1, i32* %P)
|
|
|
|
|
call void @func_strbool(i32* %P1)
|
|
|
|
|
call void @func(i32* dereferenceable(16) %P, i32* dereferenceable(8) %P)
|
|
|
|
|
call void @func(i32* dereferenceable(32) %P, i32* dereferenceable(8) %P)
|
|
|
|
|
call void @func_many(i32* align 8 %P1)
|
|
|
|
|
call void @func_argattr(i32* %P2, i32* %P3)
|
|
|
|
|
call void @func(i32* nonnull %P1, i32* nonnull %P)
|
|
|
|
@ -162,6 +207,90 @@ define i32 @test2(%struct.S* %0, i32* %1, i8* %2) {
|
|
|
|
|
; ALL-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; ALL-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; ALL-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
; WITH-AC-LABEL: @test2(
|
|
|
|
|
; WITH-AC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8), "nonnull"(%struct.S** [[TMP4]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store %struct.S* [[TMP0:%.*]], %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP5]], i64 8), "dereferenceable"(i32** [[TMP5]], i64 8), "nonnull"(i32** [[TMP5]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32* [[TMP1:%.*]], i32** [[TMP5]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8** [[TMP6]], i64 8), "nonnull"(i8** [[TMP6]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i8* [[TMP2:%.*]], i8** [[TMP6]]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP8]], i64 4), "dereferenceable"(i32* [[TMP8]], i64 4), "nonnull"(i32* [[TMP8]]) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** [[TMP6]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1), "nonnull"(i8* [[TMP11]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; WITH-AC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP17]], i64 8), "dereferenceable"(i32* [[TMP17]], i64 4), "nonnull"(i32* [[TMP17]]) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP20]], i64 4), "dereferenceable"(i8* [[TMP20]], i64 1), "nonnull"(i8* [[TMP20]]) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
|
|
|
|
|
; WITH-AC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP25]], i64 8), "dereferenceable"(i32** [[TMP25]], i64 8), "nonnull"(i32** [[TMP25]]) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP26]], i64 4), "dereferenceable"(i32* [[TMP26]], i64 4), "nonnull"(i32* [[TMP26]]) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; WITH-AC-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
; CROSS-BLOCK-LABEL: @test2(
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8), "nonnull"(%struct.S** [[TMP4]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store %struct.S* [[TMP0:%.*]], %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP5]], i64 8), "dereferenceable"(i32** [[TMP5]], i64 8), "nonnull"(i32** [[TMP5]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32* [[TMP1:%.*]], i32** [[TMP5]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8** [[TMP6]], i64 8), "nonnull"(i8** [[TMP6]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i8* [[TMP2:%.*]], i8** [[TMP6]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP8]], i64 4), "dereferenceable"(i32* [[TMP8]], i64 4), "nonnull"(i32* [[TMP8]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** [[TMP6]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1), "nonnull"(i8* [[TMP11]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP17]], i64 8), "dereferenceable"(i32* [[TMP17]], i64 4), "nonnull"(i32* [[TMP17]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP20]], i64 4), "dereferenceable"(i8* [[TMP20]], i64 1), "nonnull"(i8* [[TMP20]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP25]], i64 8), "dereferenceable"(i32** [[TMP25]], i64 8), "nonnull"(i32** [[TMP25]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP26]], i64 4), "dereferenceable"(i32* [[TMP26]], i64 4), "nonnull"(i32* [[TMP26]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
%4 = alloca %struct.S*, align 8
|
|
|
|
|
%5 = alloca i32*, align 8
|
|
|
|
@ -217,8 +346,8 @@ define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true"
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1) ]
|
|
|
|
|
; BASIC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; BASIC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; BASIC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 32), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; BASIC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
|
|
|
|
|
; BASIC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; BASIC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
@ -264,8 +393,8 @@ define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true"
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1) ]
|
|
|
|
|
; ALL-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; ALL-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; ALL-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 32), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; ALL-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
|
|
|
|
|
; ALL-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; ALL-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 8), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
@ -289,6 +418,88 @@ define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true"
|
|
|
|
|
; ALL-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; ALL-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; ALL-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
; WITH-AC-LABEL: @test3(
|
|
|
|
|
; WITH-AC-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 32), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: store %struct.S* [[TMP0:%.*]], %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP5]], i64 8), "dereferenceable"(i32** [[TMP5]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32* [[TMP1:%.*]], i32** [[TMP5]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** [[TMP6]], i64 8), "dereferenceable"(i8** [[TMP6]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: store i8* [[TMP2:%.*]], i8** [[TMP6]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP8]], i64 4), "dereferenceable"(i32* [[TMP8]], i64 4) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]]
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1) ]
|
|
|
|
|
; WITH-AC-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; WITH-AC-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
|
|
|
|
|
; WITH-AC-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; WITH-AC-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP17]], i64 8), "dereferenceable"(i32* [[TMP17]], i64 4) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP20]], i64 4), "dereferenceable"(i8* [[TMP20]], i64 1) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
|
|
|
|
|
; WITH-AC-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; WITH-AC-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32** [[TMP25]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]]
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP26]], i64 4), "dereferenceable"(i32* [[TMP26]], i64 4) ]
|
|
|
|
|
; WITH-AC-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; WITH-AC-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; WITH-AC-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
; CROSS-BLOCK-LABEL: @test3(
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP4:%.*]] = alloca %struct.S*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP5:%.*]] = alloca i32*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP6:%.*]] = alloca i8*, align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP7:%.*]] = alloca [[STRUCT_S:%.*]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(%struct.S** [[TMP4]], i64 32), "dereferenceable"(%struct.S** [[TMP4]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store %struct.S* [[TMP0:%.*]], %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32** [[TMP5]], i64 8), "dereferenceable"(i32** [[TMP5]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32* [[TMP1:%.*]], i32** [[TMP5]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8** [[TMP6]], i64 8), "dereferenceable"(i8** [[TMP6]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i8* [[TMP2:%.*]], i8** [[TMP6]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP5]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP8]], i64 4), "dereferenceable"(i32* [[TMP8]], i64 4) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP10:%.*]] = trunc i32 [[TMP9]] to i8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP11:%.*]] = load i8*, i8** [[TMP6]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8* [[TMP11]], i64 1) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i8 [[TMP10]], i8* [[TMP11]], align 1
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP12:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP13:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 32
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP14:%.*]] = bitcast %struct.S* [[TMP13]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP16]], i32 0, i32 0
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP17]], i64 8), "dereferenceable"(i32* [[TMP17]], i64 4) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 1
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP20]], i64 4), "dereferenceable"(i8* [[TMP20]], i64 1) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP20]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP22:%.*]] = sext i8 [[TMP21]] to i32
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP23:%.*]] = add nsw i32 [[TMP18]], [[TMP22]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP24:%.*]] = load %struct.S*, %struct.S** [[TMP4]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP24]], i32 0, i32 2
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32** [[TMP25]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[TMP26]], i64 4), "dereferenceable"(i32* [[TMP26]], i64 4) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP26]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: [[TMP28:%.*]] = add nsw i32 [[TMP23]], [[TMP27]]
|
|
|
|
|
; CROSS-BLOCK-NEXT: ret i32 [[TMP28]]
|
|
|
|
|
;
|
|
|
|
|
%4 = alloca %struct.S*, align 8
|
|
|
|
|
%5 = alloca i32*, align 8
|
|
|
|
@ -303,7 +514,7 @@ define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true"
|
|
|
|
|
%11 = load i8*, i8** %6
|
|
|
|
|
store i8 %10, i8* %11, align 1
|
|
|
|
|
%12 = bitcast %struct.S* %7 to i8*
|
|
|
|
|
%13 = load %struct.S*, %struct.S** %4, align 8
|
|
|
|
|
%13 = load %struct.S*, %struct.S** %4, align 32
|
|
|
|
|
%14 = bitcast %struct.S* %13 to i8*
|
|
|
|
|
%15 = bitcast %struct.S* %7 to i8*
|
|
|
|
|
%16 = load %struct.S*, %struct.S** %4, align 8
|
|
|
|
@ -321,3 +532,117 @@ define i32 @test3(%struct.S* %0, i32* %1, i8* %2) "null-pointer-is-valid"="true"
|
|
|
|
|
%28 = add nsw i32 %23, %27
|
|
|
|
|
ret i32 %28
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
define dso_local i32 @_Z6squarePi(i32* %P, i32* %P1, i1 %cond) {
|
|
|
|
|
; BASIC-LABEL: @_Z6squarePi(
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P:%.*]], i64 4), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P]], align 4
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1:%.*]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; BASIC-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
|
|
|
|
|
; BASIC: A:
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 4), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; BASIC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
|
|
|
|
|
; BASIC: B:
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; BASIC-NEXT: br label [[C]]
|
|
|
|
|
; BASIC: C:
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P]], align 32
|
|
|
|
|
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 4), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; BASIC-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; BASIC-NEXT: ret i32 0
|
|
|
|
|
;
|
|
|
|
|
; ALL-LABEL: @_Z6squarePi(
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P:%.*]], i64 4), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P]], align 4
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1:%.*]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; ALL-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
|
|
|
|
|
; ALL: A:
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 4), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; ALL-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
|
|
|
|
|
; ALL: B:
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; ALL-NEXT: br label [[C]]
|
|
|
|
|
; ALL: C:
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P]], align 32
|
|
|
|
|
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 4), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; ALL-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; ALL-NEXT: ret i32 0
|
|
|
|
|
;
|
|
|
|
|
; WITH-AC-LABEL: @_Z6squarePi(
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P:%.*]], i64 4), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P]], align 4
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1:%.*]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; WITH-AC-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
|
|
|
|
|
; WITH-AC: A:
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; WITH-AC-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
|
|
|
|
|
; WITH-AC: B:
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; WITH-AC-NEXT: br label [[C]]
|
|
|
|
|
; WITH-AC: C:
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P]], align 32
|
|
|
|
|
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 4), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; WITH-AC-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; WITH-AC-NEXT: ret i32 0
|
|
|
|
|
;
|
|
|
|
|
; CROSS-BLOCK-LABEL: @_Z6squarePi(
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P:%.*]], i64 4), "dereferenceable"(i32* [[P]], i64 4), "nonnull"(i32* [[P]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1:%.*]], i64 8), "dereferenceable"(i32* [[P1]], i64 4), "nonnull"(i32* [[P1]]) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
|
|
|
|
|
; CROSS-BLOCK: A:
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: br i1 [[COND]], label [[C:%.*]], label [[B]]
|
|
|
|
|
; CROSS-BLOCK: B:
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 8) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 8
|
|
|
|
|
; CROSS-BLOCK-NEXT: br label [[C]]
|
|
|
|
|
; CROSS-BLOCK: C:
|
|
|
|
|
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32) ]
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P]], align 32
|
|
|
|
|
; CROSS-BLOCK-NEXT: store i32 0, i32* [[P1]], align 4
|
|
|
|
|
; CROSS-BLOCK-NEXT: ret i32 0
|
|
|
|
|
;
|
|
|
|
|
store i32 0, i32* %P, align 4
|
|
|
|
|
store i32 0, i32* %P1, align 8
|
|
|
|
|
br i1 %cond, label %A, label %B
|
|
|
|
|
A:
|
|
|
|
|
store i32 0, i32* %P, align 8
|
|
|
|
|
store i32 0, i32* %P1, align 4
|
|
|
|
|
br i1 %cond, label %C, label %B
|
|
|
|
|
B:
|
|
|
|
|
store i32 0, i32* %P, align 8
|
|
|
|
|
store i32 0, i32* %P1, align 8
|
|
|
|
|
br label %C
|
|
|
|
|
C:
|
|
|
|
|
store i32 0, i32* %P, align 32
|
|
|
|
|
store i32 0, i32* %P1, align 4
|
|
|
|
|
ret i32 0
|
|
|
|
|
}
|
|
|
|
|