; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes='gvn' -S %s | FileCheck %s define i32 @store_both_arms(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @store_both_arms( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 10, i32 20 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: ret i32 [[TMP1]] ; store i32 10, ptr %p1 store i32 20, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @store_and_load(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @store_and_load( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 10, i32 [[V1]] ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[SUM:%.*]] = add i32 [[TMP1]], [[V1]] ; CHECK-NEXT: ret i32 [[SUM]] ; store i32 10, ptr %p1 %v1 = load i32, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr %sum = add i32 %v, %v1 ret i32 %sum } define i32 @store_then_load(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @store_then_load( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i32 10, i32 20 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: ret i32 [[TMP1]] ; store i32 10, ptr %p1 %v1 = load i32, ptr %p1 store i32 20, ptr %p2 %v2 = load i32, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @store_in_pred(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @store_in_pred( ; CHECK-NEXT: entry: ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[COND:%.*]], i32 10, i32 20 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: ret i32 [[TMP0]] ; entry: store i32 10, ptr %p1 store i32 20, ptr %p2 br label %bb bb: %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_volatile_store(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @negative_volatile_store( ; CHECK-NEXT: store volatile i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store volatile i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store volatile i32 10, ptr %p1 store volatile i32 20, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_store_one_arm_only(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @negative_store_one_arm_only( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2:%.*]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store i32 10, ptr %p1 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_atomic_store(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @negative_atomic_store( ; CHECK-NEXT: store atomic i32 10, ptr [[P1:%.*]] unordered, align 4 ; CHECK-NEXT: store atomic i32 20, ptr [[P2:%.*]] unordered, align 4 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store atomic i32 10, ptr %p1 unordered, align 4 store atomic i32 20, ptr %p2 unordered, align 4 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_type_mismatch(i1 %cond, ptr noalias %p1, ptr noalias %p2) { ; CHECK-LABEL: @negative_type_mismatch( ; CHECK-NEXT: store i64 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i64 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store i64 10, ptr %p1 store i64 20, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_clobber_between(i1 %cond, ptr %p1, ptr %p2) { ; CHECK-LABEL: @negative_clobber_between( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: call void @clobber() ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store i32 10, ptr %p1 store i32 20, ptr %p2 call void @clobber() %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } define i32 @negative_may_alias_stores(i1 %cond, ptr %p1, ptr %p2) { ; CHECK-LABEL: @negative_may_alias_stores( ; CHECK-NEXT: store i32 10, ptr [[P1:%.*]], align 4 ; CHECK-NEXT: store i32 20, ptr [[P2:%.*]], align 4 ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[P1]], ptr [[P2]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[ADDR]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; store i32 10, ptr %p1 store i32 20, ptr %p2 %addr = select i1 %cond, ptr %p1, ptr %p2 %v = load i32, ptr %addr ret i32 %v } declare void @clobber()