1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S -data-layout="e-m:e-i64:64-f80:128-n8:16:32:64-S128" | FileCheck %s 3 4@a = global [1000 x float] zeroinitializer, align 16 5@b = global [1000 x float] zeroinitializer, align 16 6 7define void @_Z3foov() { 8; CHECK-LABEL: @_Z3foov( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: br label [[FOR_COND:%.*]] 11; CHECK: for.cond: 12; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] 13; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[I_0]], 1000 14; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] 15; CHECK: for.cond.cleanup: 16; CHECK-NEXT: ret void 17; CHECK: for.body: 18; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[I_0]] to i64 19; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [1000 x float], ptr @a, i64 0, i64 [[TMP0]] 20; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [1000 x float], ptr @b, i64 0, i64 [[TMP0]] 21; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX]], align 4 22; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX2]], align 4 23; CHECK-NEXT: [[CMP_I:%.*]] = fcmp fast olt float [[TMP1]], [[TMP2]] 24; CHECK-NEXT: [[DOTV:%.*]] = select i1 [[CMP_I]], float [[TMP2]], float [[TMP1]] 25; CHECK-NEXT: store float [[DOTV]], ptr [[ARRAYIDX]], align 4 26; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1 27; CHECK-NEXT: br label [[FOR_COND]] 28; 29entry: 30 br label %for.cond 31 32for.cond: ; preds = %for.body, %entry 33 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 34 %cmp = icmp ult i32 %i.0, 1000 35 br i1 %cmp, label %for.body, label %for.cond.cleanup 36 37for.cond.cleanup: ; preds = %for.cond 38 ret void 39 40for.body: ; preds = %for.cond 41 %0 = zext i32 %i.0 to i64 42 %arrayidx = getelementptr inbounds [1000 x float], ptr @a, i64 0, i64 %0 43 %arrayidx2 = getelementptr inbounds [1000 x float], ptr @b, i64 0, i64 %0 44 %1 = load float, ptr %arrayidx, align 4 45 %2 = load float, ptr %arrayidx2, align 4 46 %cmp.i = fcmp fast olt float %1, %2 47 %__b.__a.i = select i1 %cmp.i, ptr %arrayidx2, ptr %arrayidx 48 %3 = load i32, ptr %__b.__a.i, align 4 49 store i32 %3, ptr %arrayidx, align 4 50 %inc = add nuw nsw i32 %i.0, 1 51 br label %for.cond 52} 53 54define i32 @store_bitcasted_load(i1 %cond, ptr dereferenceable(4) %addr1, ptr dereferenceable(4) %addr2) { 55; CHECK-LABEL: @store_bitcasted_load( 56; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR1:%.*]], ptr [[ADDR2:%.*]] 57; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[SEL]], align 4 58; CHECK-NEXT: ret i32 [[LD]] 59; 60 %sel = select i1 %cond, ptr %addr1, ptr %addr2 61 %ld = load i32, ptr %sel 62 ret i32 %ld 63} 64 65define void @bitcasted_store(i1 %cond, ptr %loadaddr1, ptr %loadaddr2, ptr %storeaddr) { 66; CHECK-LABEL: @bitcasted_store( 67; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[LOADADDR1:%.*]], ptr [[LOADADDR2:%.*]] 68; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[SEL]], align 4 69; CHECK-NEXT: store i32 [[LD]], ptr [[STOREADDR:%.*]], align 4 70; CHECK-NEXT: ret void 71; 72 %sel = select i1 %cond, ptr %loadaddr1, ptr %loadaddr2 73 %ld = load i32, ptr %sel 74 store i32 %ld, ptr %storeaddr 75 ret void 76} 77 78define void @bitcasted_minmax_with_select_of_pointers(ptr %loadaddr1, ptr %loadaddr2, ptr %storeaddr) { 79; CHECK-LABEL: @bitcasted_minmax_with_select_of_pointers( 80; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[LOADADDR1:%.*]], align 4 81; CHECK-NEXT: [[LD2:%.*]] = load float, ptr [[LOADADDR2:%.*]], align 4 82; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[LD1]], [[LD2]] 83; CHECK-NEXT: [[LD_V:%.*]] = select i1 [[COND]], float [[LD1]], float [[LD2]] 84; CHECK-NEXT: store float [[LD_V]], ptr [[STOREADDR:%.*]], align 4 85; CHECK-NEXT: ret void 86; 87 %ld1 = load float, ptr %loadaddr1, align 4 88 %ld2 = load float, ptr %loadaddr2, align 4 89 %cond = fcmp ogt float %ld1, %ld2 90 %sel = select i1 %cond, ptr %loadaddr1, ptr %loadaddr2 91 %ld = load i32, ptr %sel, align 4 92 store i32 %ld, ptr %storeaddr, align 4 93 ret void 94} 95