1 ; RUN: opt -simplifycfg -S < %s | FileCheck %s 2 3 define void @ifconvertstore(i32* %A, i32 %B, i32 %C, i32 %D) { 4 ; CHECK-LABEL: @ifconvertstore( 5 ; CHECK: store i32 %B, i32* %A 6 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %D, 42 7 ; CHECK-NEXT: [[C_B:%.*]] = select i1 [[CMP]], i32 %C, i32 %B, !prof !0 8 ; CHECK-NEXT: store i32 [[C_B]], i32* %A 9 ; CHECK-NEXT: ret void 10 ; 11 entry: 12 ; First store to the location. 13 store i32 %B, i32* %A 14 %cmp = icmp sgt i32 %D, 42 15 br i1 %cmp, label %if.then, label %ret.end, !prof !0 16 17 ; Make sure we speculate stores like the following one. It is cheap compared to 18 ; a mispredicated branch. 19 if.then: 20 store i32 %C, i32* %A 21 br label %ret.end 22 23 ret.end: 24 ret void 25 } 26 27 ; Store to a different location. 28 29 define void @noifconvertstore1(i32* %A1, i32* %A2, i32 %B, i32 %C, i32 %D) { 30 ; CHECK-LABEL: @noifconvertstore1( 31 ; CHECK-NOT: select 32 ; 33 entry: 34 store i32 %B, i32* %A1 35 %cmp = icmp sgt i32 %D, 42 36 br i1 %cmp, label %if.then, label %ret.end 37 38 if.then: 39 store i32 %C, i32* %A2 40 br label %ret.end 41 42 ret.end: 43 ret void 44 } 45 46 ; This function could store to our address, so we can't repeat the first store a second time. 47 declare void @unknown_fun() 48 49 define void @noifconvertstore2(i32* %A, i32 %B, i32 %C, i32 %D) { 50 ; CHECK-LABEL: @noifconvertstore2( 51 ; CHECK-NOT: select 52 ; 53 entry: 54 ; First store to the location. 55 store i32 %B, i32* %A 56 call void @unknown_fun() 57 %cmp6 = icmp sgt i32 %D, 42 58 br i1 %cmp6, label %if.then, label %ret.end 59 60 if.then: 61 store i32 %C, i32* %A 62 br label %ret.end 63 64 ret.end: 65 ret void 66 } 67 68 ; Make sure we don't speculate volatile stores. 69 70 define void @noifconvertstore_volatile(i32* %A, i32 %B, i32 %C, i32 %D) { 71 ; CHECK-LABEL: @noifconvertstore_volatile( 72 ; CHECK-NOT: select 73 ; 74 entry: 75 ; First store to the location. 76 store i32 %B, i32* %A 77 %cmp6 = icmp sgt i32 %D, 42 78 br i1 %cmp6, label %if.then, label %ret.end 79 80 if.then: 81 store volatile i32 %C, i32* %A 82 br label %ret.end 83 84 ret.end: 85 ret void 86 } 87 88 ; CHECK: !0 = !{!"branch_weights", i32 3, i32 5} 89 !0 = !{!"branch_weights", i32 3, i32 5} 90 91