189 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; Check that we don't create two redundant phi nodes when %val is used in a5; form where we can't rewrite it in terms of the new phi node.6 7; Use %val in an instruction type not supported by optimizeBitCastFromPhi.8define float @sitofp(float %x) {9; CHECK-LABEL: @sitofp(10; CHECK-NEXT: entry:11; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]12; CHECK: loop_header:13; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAL_INCR_CASTED:%.*]], [[LOOP:%.*]] ]14; CHECK-NEXT: [[VAL_CASTED:%.*]] = bitcast i32 [[VAL]] to float15; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[VAL_CASTED]]16; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[LOOP]]17; CHECK: loop:18; CHECK-NEXT: [[VAL_INCR:%.*]] = fadd float [[VAL_CASTED]], 1.000000e+0019; CHECK-NEXT: [[VAL_INCR_CASTED]] = bitcast float [[VAL_INCR]] to i3220; CHECK-NEXT: br label [[LOOP_HEADER]]21; CHECK: end:22; CHECK-NEXT: [[RESULT:%.*]] = sitofp i32 [[VAL]] to float23; CHECK-NEXT: ret float [[RESULT]]24;25entry:26 br label %loop_header27loop_header:28 %val = phi i32 [ 0, %entry ], [ %val_incr_casted, %loop ]29 %val_casted = bitcast i32 %val to float30 %cmp = fcmp ogt float %val_casted, %x31 br i1 %cmp, label %end, label %loop32loop:33 %val_incr = fadd float %val_casted, 1.034 %val_incr_casted = bitcast float %val_incr to i3235 br label %loop_header36end:37 %result = sitofp i32 %val to float38 ret float %result39}40 41; Use %val in an incompatible bitcast.42define <2 x i16> @bitcast(float %x) {43; CHECK-LABEL: @bitcast(44; CHECK-NEXT: entry:45; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]46; CHECK: loop_header:47; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAL_INCR_CASTED:%.*]], [[LOOP:%.*]] ]48; CHECK-NEXT: [[VAL_CASTED:%.*]] = bitcast i32 [[VAL]] to float49; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[VAL_CASTED]]50; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[LOOP]]51; CHECK: loop:52; CHECK-NEXT: [[VAL_INCR:%.*]] = fadd float [[VAL_CASTED]], 1.000000e+0053; CHECK-NEXT: [[VAL_INCR_CASTED]] = bitcast float [[VAL_INCR]] to i3254; CHECK-NEXT: br label [[LOOP_HEADER]]55; CHECK: end:56; CHECK-NEXT: [[RESULT:%.*]] = bitcast i32 [[VAL]] to <2 x i16>57; CHECK-NEXT: ret <2 x i16> [[RESULT]]58;59entry:60 br label %loop_header61loop_header:62 %val = phi i32 [ 0, %entry ], [ %val_incr_casted, %loop ]63 %val_casted = bitcast i32 %val to float64 %cmp = fcmp ogt float %val_casted, %x65 br i1 %cmp, label %end, label %loop66loop:67 %val_incr = fadd float %val_casted, 1.068 %val_incr_casted = bitcast float %val_incr to i3269 br label %loop_header70end:71 %result = bitcast i32 %val to <2 x i16>72 ret <2 x i16> %result73}74 75@global = global i32 076 77; Use %val with a volatile store.78define void @store_volatile(float %x) {79; CHECK-LABEL: @store_volatile(80; CHECK-NEXT: entry:81; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]82; CHECK: loop_header:83; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAL_INCR_CASTED:%.*]], [[LOOP:%.*]] ]84; CHECK-NEXT: [[VAL_CASTED:%.*]] = bitcast i32 [[VAL]] to float85; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[VAL_CASTED]]86; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[LOOP]]87; CHECK: loop:88; CHECK-NEXT: [[VAL_INCR:%.*]] = fadd float [[VAL_CASTED]], 1.000000e+0089; CHECK-NEXT: [[VAL_INCR_CASTED]] = bitcast float [[VAL_INCR]] to i3290; CHECK-NEXT: br label [[LOOP_HEADER]]91; CHECK: end:92; CHECK-NEXT: store volatile i32 [[VAL]], ptr @global, align 493; CHECK-NEXT: ret void94;95entry:96 br label %loop_header97loop_header:98 %val = phi i32 [ 0, %entry ], [ %val_incr_casted, %loop ]99 %val_casted = bitcast i32 %val to float100 %cmp = fcmp ogt float %val_casted, %x101 br i1 %cmp, label %end, label %loop102loop:103 %val_incr = fadd float %val_casted, 1.0104 %val_incr_casted = bitcast float %val_incr to i32105 br label %loop_header106end:107 store volatile i32 %val, ptr @global108 ret void109}110 111; Use %val with a store where it's actually the address.112define void @store_address(i32 %x) {113; CHECK-LABEL: @store_address(114; CHECK-NEXT: entry:115; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]116; CHECK: loop_header:117; CHECK-NEXT: [[VAL:%.*]] = phi ptr [ @global, [[ENTRY:%.*]] ], [ [[VAL_INCR:%.*]], [[LOOP:%.*]] ]118; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0119; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[LOOP]]120; CHECK: loop:121; CHECK-NEXT: [[VAL_INCR]] = getelementptr i8, ptr [[VAL]], i64 4122; CHECK-NEXT: br label [[LOOP_HEADER]]123; CHECK: end:124; CHECK-NEXT: store i32 0, ptr [[VAL]], align 4125; CHECK-NEXT: ret void126;127entry:128 br label %loop_header129loop_header:130 %val = phi ptr [ @global, %entry ], [ %val_incr, %loop ]131 %i = phi i32 [ 0, %entry ], [ %i_incr, %loop ]132 %cmp = icmp sgt i32 %i, %x133 br i1 %cmp, label %end, label %loop134loop:135 %i_incr = add i32 %i, 0136 %val_incr = getelementptr float, ptr %val, i32 1137 br label %loop_header138end:139 store i32 0, ptr %val140 ret void141}142 143; Test where a phi (%val2) other than the original one (%val) has an144; incompatible use.145define i32 @multiple_phis(float %x) {146; CHECK-LABEL: @multiple_phis(147; CHECK-NEXT: entry:148; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]149; CHECK: loop_header:150; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAL2:%.*]], [[LOOP_END:%.*]] ]151; CHECK-NEXT: [[VAL_CASTED:%.*]] = bitcast i32 [[VAL]] to float152; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[VAL_CASTED]]153; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[LOOP:%.*]]154; CHECK: loop:155; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[VAL_CASTED]], 2.000000e+00156; CHECK-NEXT: br i1 [[CMP2]], label [[IF:%.*]], label [[LOOP_END]]157; CHECK: if:158; CHECK-NEXT: [[VAL_INCR:%.*]] = fadd float [[VAL_CASTED]], 1.000000e+00159; CHECK-NEXT: [[VAL_INCR_CASTED:%.*]] = bitcast float [[VAL_INCR]] to i32160; CHECK-NEXT: br label [[LOOP_END]]161; CHECK: loop_end:162; CHECK-NEXT: [[VAL2]] = phi i32 [ [[VAL]], [[LOOP]] ], [ [[VAL_INCR_CASTED]], [[IF]] ]163; CHECK-NEXT: store volatile i32 [[VAL2]], ptr @global, align 4164; CHECK-NEXT: br label [[LOOP_HEADER]]165; CHECK: end:166; CHECK-NEXT: ret i32 [[VAL]]167;168entry:169 br label %loop_header170loop_header:171 %val = phi i32 [ 0, %entry ], [ %val2, %loop_end ]172 %val_casted = bitcast i32 %val to float173 %cmp = fcmp ogt float %val_casted, %x174 br i1 %cmp, label %end, label %loop175loop:176 %cmp2 = fcmp ogt float %val_casted, 2.0177 br i1 %cmp2, label %if, label %loop_end178if:179 %val_incr = fadd float %val_casted, 1.0180 %val_incr_casted = bitcast float %val_incr to i32181 br label %loop_end182loop_end:183 %val2 = phi i32 [ %val, %loop ], [ %val_incr_casted, %if ]184 store volatile i32 %val2, ptr @global ; the incompatible use185 br label %loop_header186end:187 ret i32 %val188}189